package com.alibaba.citrus.ots.application.report.ability.facade.service;

import com.alibaba.citrus.ots.application.report.ability.repository.BaseDataQueryRepository;
import com.alibaba.citrus.ots.application.report.ability.repository.MonthSalesBasicReportQueryRepository;
import com.alibaba.citrus.ots.application.report.ability.repository.MonthSalesCategoryReportQueryRepository;
import com.alibaba.citrus.ots.application.report.ability.repository.MonthSalesChannelRankReportQueryRepository;
import com.alibaba.citrus.ots.application.report.ability.repository.MonthSalesDepartmentRankReportQueryRepository;
import com.alibaba.citrus.ots.application.report.ability.repository.MonthSalesEmployeeRankReportQueryRepository;
import com.alibaba.citrus.ots.application.report.ability.repository.PlanContractQuantityRepository;
import com.alibaba.citrus.ots.application.report.ability.utils.DomUtil;
import com.alibaba.citrus.ots.application.report.ability.utils.PageRecordUtil;
import com.alibaba.citrus.ots.application.report.ability.utils.SubtotalViewVOUtil;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.citrus.ots.sales.plan.model.enums.ContractDataSourceEnum;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.CategorySDO;
import com.epoch.app.bcorder.model.dto.OrganizationSDO;
import com.epoch.app.bcorder.sales_plan.contract.model.Contract;
import com.epoch.app.crplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.crplatformenhance.dto.request.IdQueryRequest;
import com.epoch.app.crplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.otsapplicationreportsdk.model.dto.BatchQueryContractQuantityRequest;
import com.epoch.app.otsapplicationreportsdk.model.dto.MonthSalesBasicReportSDO;
import com.epoch.app.otsapplicationreportsdk.model.dto.MonthSalesProgressReportAppViewVO;
import com.epoch.app.otsapplicationreportsdk.model.dto.MonthSalesProgressReportExcelVO;
import com.epoch.app.otsapplicationreportsdk.model.dto.MonthSalesProgressReportVO;
import com.epoch.app.otsapplicationreportsdk.model.dto.MonthSalesProgressReportViewListVO;
import com.epoch.app.otsapplicationreportsdk.model.dto.MonthSalesProgressReportViewVO;
import com.epoch.app.otsapplicationreportsdk.model.dto.QueryMonthSalesReportRequest;
import com.epoch.app.otsapplicationreportsdk.model.dto.RankAppComponent;
import com.epoch.app.otsapplicationreportsdk.model.dto.RankAppComponentChildren;
import com.epoch.app.otsapplicationreportsdk.model.dto.RankAppComponentContent;
import com.epoch.app.otsapplicationreportsdk.model.dto.RankAppComponentData;
import com.epoch.app.otsapplicationreportsdk.model.dto.RankData;
import com.epoch.app.otsapplicationreportsdk.model.dto.RankTab;
import com.epoch.app.otsapplicationreportsdk.model.dto.RankViewVO;
import com.epoch.app.otsapplicationreportsdk.model.dto.SubtotalViewVO;
import com.epoch.app.otsapplicationreportsdk.monthsalesprogressreportquery.service.MonthSalesProgressReportQueryService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhoubc
 * @description: TODO
 * @date 2021/12/1 20:59
 */
@Primary
@Component
public class MonthSalesProgressReportServiceImpl implements MonthSalesProgressReportQueryService {

    private final String GROUPBY_DATE = "statistical_date";
    private final String GROUPBY_BUSINESSUNIT = "org_business_unit_id";
    private final String GROUPBY_CHANNEL = "org_sales_channel_id";
    private final String GROUPBY_DEPARTMENT = "org_sales_department_id";

    private final String CHANNEL_RANK = "channelRank";
    private final String DEPARTMENT_RANK = "departmentRank";
    private final String EMPLOYEE_RANK = "employeeRank";
    private final String CATEGORY = "category";
    private final String COMPANY_CATEGORY = "company_category";

    private final String CUSTOMER_RANK = "customer";
    private final String SCITEM_RANK = "scItem";
    private final String CATEGORY_RANK = "category";

    @Resource
    BaseDataQueryRepository baseDataQueryRepository;
    @Resource
    OrganizationQueryService organizationQueryService;
    @Resource
    MonthSalesBasicReportQueryRepository monthSalesBasicReportQueryRepository;
    @Resource
    MonthSalesEmployeeRankReportQueryRepository monthSalesEmployeeRankReportQueryRepository;
    @Resource
    MonthSalesDepartmentRankReportQueryRepository monthSalesDepartmentRankReportQueryRepository;
    @Resource
    MonthSalesChannelRankReportQueryRepository monthSalesChannelRankReportQueryRepository;
    @Resource
    MonthSalesCategoryReportQueryRepository monthSalesCategoryReportQueryRepository;
    @Resource
    PlanContractQuantityRepository planContractQuantityRepository;

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportVO>> pageQueryMonthSalesBasicReportList(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //组装查询组织
        //assembleQueryOrganization(queryMonthSalesReportRequest);
        //组装查询货品类目
        List<String> categoryIds = queryMonthSalesReportRequest.getScItemCategoryIds();
        if(CollectionUtils.isNotEmpty(categoryIds)){
            //查询类目可能是蒙牛常温等根类目，要排除这种情况
            categoryIds = categoryIds.stream().filter(x -> !x.startsWith("###")).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(categoryIds)){
                List<String> scItemRootCategoryIds = new ArrayList();
                List<String> scItemLeafCategoryIds = new ArrayList();
                List<CategorySDO> categoryList = baseDataQueryRepository.batchQueryCategoryGetList(categoryIds);
                categoryList.forEach(x -> {
                    if(Objects.equals(x.getRootCategoryId(), x.getParentCategoryId())){
                        scItemRootCategoryIds.add(x.getCategoryId());
                    }else{
                        scItemLeafCategoryIds.add(x.getCategoryId());
                    }
                });
                queryMonthSalesReportRequest.setScItemRootCategoryIds(scItemRootCategoryIds);
                queryMonthSalesReportRequest.setScItemLeafCategoryIds(scItemLeafCategoryIds);
            }
        }

        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesBasicReportQueryRepository.pageQueryMonthSalesBasicReportList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportVO> converterResult = null;
        Result<List<SubtotalViewVO>> viewResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
            viewResult = initSubtotalViewVO();
        }else {
            //填充部门小计，渠道合计，公司总计
            insertTotalRow(listResult,queryMonthSalesReportRequest);
            //数据格式转换
            converterResult = converterVO(listResult);
            //查询表头的数据统计
            Result<List<SubtotalViewVO>> response = getSubtotalViewData(queryMonthSalesReportRequest,"");
            viewResult = response;
        }
        Map<String,Object> ext = new HashMap<>();
        ext.put("statistic",viewResult.getResult());
        String progressValue = DomUtil.getProgressValue(queryMonthSalesReportRequest.getStatisticalDate());
        ext.put("progress", progressValue.substring(0,progressValue.length()-1));
        Result result = Result.listSuccess(converterResult,pageResult.getTotal());
        result.setExt(ext);
        return result;
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportVO>> pageQueryMonthSalesEmployeeRankReportList(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //组装查询组织
        //assembleQueryOrganization(queryMonthSalesReportRequest);
        //排序
        setDir(queryMonthSalesReportRequest);
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesEmployeeRankReportQueryRepository.pageQueryMonthSalesEmployeeBankReportList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportVO> converterResult = null;
        Result<List<SubtotalViewVO>> viewResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
            viewResult = initSubtotalViewVO();
        }else {
            //重新赋值排序号
            resetEmployeeRankSortNo(queryMonthSalesReportRequest,listResult);
            //数据格式转换
            converterResult = converterVO(listResult);
            //查询表头的数据统计
            Result<List<SubtotalViewVO>> response = getSubtotalViewData(queryMonthSalesReportRequest,EMPLOYEE_RANK);
            viewResult = response;
        }
        Map<String,Object> ext = new HashMap<>();
        ext.put("statistic",viewResult.getResult());
        String progressValue = DomUtil.getProgressValue(queryMonthSalesReportRequest.getStatisticalDate());
        ext.put("progress", progressValue.substring(0,progressValue.length()-1));
        Result result = Result.listSuccess(converterResult,pageResult.getTotal());
        result.setExt(ext);
        return result;
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportVO>> pageQueryMonthSalesDepartmentRankReportList(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //组装查询组织
        //assembleQueryOrganization(queryMonthSalesReportRequest);
        //排序
        setDir(queryMonthSalesReportRequest);
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesDepartmentRankReportQueryRepository.pageQueryMonthSalesDepartmentBankReportList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportVO> converterResult = null;
        Result<List<SubtotalViewVO>> viewResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
            viewResult = initSubtotalViewVO();
        }else {
            //重新赋值排序号
            resetDepartmentRankSortNo(queryMonthSalesReportRequest,listResult);
            //数据格式转换
            converterResult = converterVO(listResult);
            //查询表头的数据统计
            Result<List<SubtotalViewVO>> response = getSubtotalViewData(queryMonthSalesReportRequest,DEPARTMENT_RANK);
            viewResult = response;
        }
        Map<String,Object> ext = new HashMap<>();
        ext.put("statistic",viewResult.getResult());
        String progressValue = DomUtil.getProgressValue(queryMonthSalesReportRequest.getStatisticalDate());
        ext.put("progress", progressValue.substring(0,progressValue.length()-1));
        Result result = Result.listSuccess(converterResult,pageResult.getTotal());
        result.setExt(ext);
        return result;
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportVO>> pageQueryMonthSalesChannelRankReportList(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //部门用户查询直接返回空值
        if(CollectionUtils.isNotEmpty(queryMonthSalesReportRequest.getOrgSalesDepartmentIds())){
            Map<String,Object> ext = new HashMap<>();
            ext.put("statistic",initSubtotalViewVO());
            Result result = Result.listSuccess(new ArrayList<MonthSalesProgressReportVO>(),0);
            result.setExt(ext);
            return result;
        }
        //组装查询组织
        //assembleQueryOrganization(queryMonthSalesReportRequest);
        //排序
        setDir(queryMonthSalesReportRequest);
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesChannelRankReportQueryRepository.pageQueryMonthSalesChannelBankReportList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportVO> converterResult = null;
        Result<List<SubtotalViewVO>> viewResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
            viewResult = initSubtotalViewVO();
        }else {
            //重新赋值排序号
            resetChannelRankSortNo(queryMonthSalesReportRequest,listResult);
            //数据格式转换
            converterResult = converterVO(listResult);
            //查询表头的数据统计
            Result<List<SubtotalViewVO>> response = getSubtotalViewData(queryMonthSalesReportRequest,CHANNEL_RANK);
            viewResult = response;
        }
        Map<String,Object> ext = new HashMap<>();
        ext.put("statistic",viewResult.getResult());
        String progressValue = DomUtil.getProgressValue(queryMonthSalesReportRequest.getStatisticalDate());
        ext.put("progress", progressValue.substring(0,progressValue.length()-1));
        Result result = Result.listSuccess(converterResult,pageResult.getTotal());
        result.setExt(ext);
        return result;
    }

    private void resetEmployeeRankSortNo(QueryMonthSalesReportRequest request,List<MonthSalesBasicReportSDO> listResult){
        QueryMonthSalesReportRequest queryRequest = QueryMonthSalesReportRequest.builder()
                .statisticalDate(request.getStatisticalDate())
                .build();
        if(Integer.parseInt(request.getUserOrgType())>=103){
            IdQueryRequest idQueryRequest = new IdQueryRequest();
            idQueryRequest.setId(request.getUserOrgId());
            idQueryRequest.setType(OrganizationTypeEnum.COMPANY.getCode());
            Result<List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO>> orgs = organizationQueryService.getTopOrganizationList(idQueryRequest);
            List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO> list = orgs.getResult();
            queryRequest.setOrgBusinessUnitIds(Lists.newArrayList(list.get(list.size()-1).getId()));
        }else if("1".equals(request.getMark())&&Integer.parseInt(request.getUserOrgType())<103){
            queryRequest.setOrgBusinessUnitIds(Lists.newArrayList(request.getOrgCompany()));
        }else{
            //return;
        }
        List<MonthSalesBasicReportSDO> result = generateSortNo(queryRequest, EMPLOYEE_RANK);
        Map<String,MonthSalesBasicReportSDO> resultMap = result.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getId,Function.identity(),(v1,v2)->v1));
        listResult.forEach( x->{
            MonthSalesBasicReportSDO tmp = resultMap.get(x.getId());
            if(tmp != null){
                x.setTaskCountCompleteRankNo(tmp.getTaskCountCompleteRankNo());
                x.setBeforeMonthMoneyCompleteRankNo(tmp.getBeforeMonthMoneyCompleteRankNo());
                x.setMonthMoneyCompleteRankNo(tmp.getMonthMoneyCompleteRankNo());
                x.setContractMoneyCompleteRankNo(tmp.getContractMoneyCompleteRankNo());
            }else{
                x.setTaskCountCompleteRankNo(null);
                x.setBeforeMonthMoneyCompleteRankNo(null);
                x.setMonthMoneyCompleteRankNo(null);
                x.setContractMoneyCompleteRankNo(null);
            }
        });
    }

    private void resetDepartmentRankSortNo(QueryMonthSalesReportRequest request,List<MonthSalesBasicReportSDO> listResult) {
        QueryMonthSalesReportRequest queryRequest = QueryMonthSalesReportRequest.builder()
                .statisticalDate(request.getStatisticalDate())
                .build();
        if(Integer.parseInt(request.getUserOrgType())>=103){
            IdQueryRequest idQueryRequest = new IdQueryRequest();
            idQueryRequest.setId(request.getUserOrgId());
            idQueryRequest.setType(OrganizationTypeEnum.COMPANY.getCode());
            Result<List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO>> orgs = organizationQueryService.getTopOrganizationList(idQueryRequest);
            List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO> list = orgs.getResult();
            queryRequest.setOrgBusinessUnitIds(Lists.newArrayList(list.get(list.size()-1).getId()));
        }else if("1".equals(request.getMark())&&Integer.parseInt(request.getUserOrgType())<103){
            queryRequest.setOrgBusinessUnitIds(Lists.newArrayList(request.getOrgCompany()));
        }else{
            //return;
        }
        List<MonthSalesBasicReportSDO> result = generateSortNo(queryRequest, DEPARTMENT_RANK);
        Map<String,MonthSalesBasicReportSDO> resultMap = result.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgSalesDepartmentId,Function.identity(),(v1,v2)->v1));
        listResult.forEach( x->{
            MonthSalesBasicReportSDO tmp = resultMap.get(x.getOrgSalesDepartmentId());
            if(tmp != null){
                x.setTaskCountCompleteRankNo(tmp.getTaskCountCompleteRankNo());
                x.setBeforeMonthMoneyCompleteRankNo(tmp.getBeforeMonthMoneyCompleteRankNo());
                x.setMonthMoneyCompleteRankNo(tmp.getMonthMoneyCompleteRankNo());
                x.setContractMoneyCompleteRankNo(tmp.getContractMoneyCompleteRankNo());
            }else{
                x.setTaskCountCompleteRankNo(null);
                x.setBeforeMonthMoneyCompleteRankNo(null);
                x.setMonthMoneyCompleteRankNo(null);
                x.setContractMoneyCompleteRankNo(null);
            }
        });
    }

    private void resetChannelRankSortNo(QueryMonthSalesReportRequest request,List<MonthSalesBasicReportSDO> listResult){
        QueryMonthSalesReportRequest queryRequest = QueryMonthSalesReportRequest.builder()
                .statisticalDate(request.getStatisticalDate())
                .build();
        if(Integer.parseInt(request.getUserOrgType())>=103){
            IdQueryRequest idQueryRequest = new IdQueryRequest();
            idQueryRequest.setId(request.getUserOrgId());
            idQueryRequest.setType(OrganizationTypeEnum.COMPANY.getCode());
            Result<List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO>> orgs = organizationQueryService.getTopOrganizationList(idQueryRequest);
            List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO> list = orgs.getResult();
            queryRequest.setOrgBusinessUnitIds(Lists.newArrayList(list.get(list.size()-1).getId()));
        }else if("1".equals(request.getMark())&&Integer.parseInt(request.getUserOrgType())<103){
            queryRequest.setOrgBusinessUnitIds(Lists.newArrayList(request.getOrgCompany()));
        }else{
            //return;
        }
        List<MonthSalesBasicReportSDO> result = generateSortNo(queryRequest, CHANNEL_RANK);
        Map<String,MonthSalesBasicReportSDO> resultMap = result.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgSalesChannelId,Function.identity(),(v1,v2)->v1));
        listResult.forEach( x->{
            MonthSalesBasicReportSDO tmp = resultMap.get(x.getOrgSalesChannelId());
            if(tmp != null){
                x.setTaskCountCompleteRankNo(tmp.getTaskCountCompleteRankNo());
                x.setBeforeMonthMoneyCompleteRankNo(tmp.getBeforeMonthMoneyCompleteRankNo());
                x.setMonthMoneyCompleteRankNo(tmp.getMonthMoneyCompleteRankNo());
                x.setContractMoneyCompleteRankNo(tmp.getContractMoneyCompleteRankNo());
            }else{
                x.setTaskCountCompleteRankNo(null);
                x.setBeforeMonthMoneyCompleteRankNo(null);
                x.setMonthMoneyCompleteRankNo(null);
                x.setContractMoneyCompleteRankNo(null);
            }
        });
    }

    private List<MonthSalesBasicReportSDO> generateSortNo(QueryMonthSalesReportRequest queryRequest,String type){
        List<MonthSalesBasicReportSDO> allData = new ArrayList<>();
        PageRecordUtil pageUtil = new PageRecordUtil();
        pageUtil.resetPageParam();
        queryRequest.setLimit(pageUtil.getPageSize());
        //任务完成量排序
        queryRequest.setDir("task_count_complete");
        queryRequest.setSortType("desc");
        for (int i = 1; i <= pageUtil.getPage(); i++) {
            queryRequest.setStart(pageUtil.getStart());
            PageResult<List<MonthSalesBasicReportSDO>> pageResult = null;
            if(EMPLOYEE_RANK.equals(type)){
                pageResult = monthSalesEmployeeRankReportQueryRepository.pageQueryMonthSalesEmployeeBankReportList(queryRequest);
            }else if(DEPARTMENT_RANK.equals(type)){
                pageResult = monthSalesDepartmentRankReportQueryRepository.pageQueryMonthSalesDepartmentBankReportList(queryRequest);
            }else if(CHANNEL_RANK.equals(type)){
                pageResult = monthSalesChannelRankReportQueryRepository.pageQueryMonthSalesChannelBankReportList(queryRequest);
            }
            if(i == 1){
                pageUtil.setTotalPages(pageResult.getTotal());
            }
//            for(MonthSalesBasicReportSDO x:pageResult.getContent()){
//                x.setTaskCountCompleteRankNo(com.google.common.base.Objects.equal(pageUtil.getLastTaskCountCompletePercentage(),x.getTaskCountCompletePercentage())?pageUtil.getLastSameSortNo():pageUtil.getNewSortNoAndRecordLastSortNo());
//                pageUtil.recordTaskCountCompletePercentage(x.getTaskCountCompletePercentage());
//                pageUtil.sortNoIncrease();
//            };
            allData.addAll(pageResult.getContent());
            pageUtil.turnPage();
        }
        //已达成排序
        allData = allData.stream().sorted((s1,s2) -> s2.getTaskCountCompletePercentage().compareTo(s1.getTaskCountCompletePercentage())).collect(Collectors.toList());
        pageUtil.resetPageParam();
        for (MonthSalesBasicReportSDO datum : allData) {
            datum.setTaskCountCompleteRankNo(pageUtil.getLastTaskCountCompletePercentage().compareTo(datum.getTaskCountCompletePercentage()) == 0 ? pageUtil.getLastSameSortNo() : pageUtil.getNewSortNoAndRecordLastSortNo());
            pageUtil.setLastTaskCountCompletePercentage(datum.getTaskCountCompletePercentage());
            pageUtil.sortNoIncrease();
        }
        //补全折前金额已达成排序
        allData = allData.stream().sorted((s1,s2) -> s2.getBeforeMonthMoneyCompletePercentage().compareTo(s1.getBeforeMonthMoneyCompletePercentage())).collect(Collectors.toList());
        pageUtil.resetPageParam();
        for (MonthSalesBasicReportSDO allDatum : allData) {
            allDatum.setBeforeMonthMoneyCompleteRankNo(pageUtil.getLastMonthMoneyCompletePercentage().compareTo(allDatum.getBeforeMonthMoneyCompletePercentage()) == 0 ? pageUtil.getLastSameSortNo() : pageUtil.getNewSortNoAndRecordLastSortNo());
            pageUtil.recordlastMonthMoneyCompletePercentage(allDatum.getBeforeMonthMoneyCompletePercentage());
            pageUtil.sortNoIncrease();
        }
        //补全折后金额已达成排序
        allData = allData.stream().sorted((s1,s2) -> s2.getMonthMoneyCompletePercentage().compareTo(s1.getMonthMoneyCompletePercentage())).collect(Collectors.toList());
        pageUtil.resetPageParam();
        for (MonthSalesBasicReportSDO allDatum : allData) {
            allDatum.setMonthMoneyCompleteRankNo(pageUtil.getLastMonthMoneyCompletePercentage().compareTo(allDatum.getMonthMoneyCompletePercentage()) == 0 ? pageUtil.getLastSameSortNo() : pageUtil.getNewSortNoAndRecordLastSortNo());
            pageUtil.recordlastMonthMoneyCompletePercentage(allDatum.getMonthMoneyCompletePercentage());
            pageUtil.sortNoIncrease();
        }
        //补全折后合同金额已达成排序
        allData = allData.stream().sorted((s1,s2) -> s2.getContractMoneyCompletePercentage().compareTo(s1.getContractMoneyCompletePercentage())).collect(Collectors.toList());
        pageUtil.resetPageParam();
        for (MonthSalesBasicReportSDO allDatum : allData) {
            allDatum.setContractMoneyCompleteRankNo(pageUtil.getLastMonthMoneyCompletePercentage().compareTo(allDatum.getContractMoneyCompletePercentage()) == 0 ? pageUtil.getLastSameSortNo() : pageUtil.getNewSortNoAndRecordLastSortNo());
            pageUtil.recordlastMonthMoneyCompletePercentage(allDatum.getContractMoneyCompletePercentage());
            pageUtil.sortNoIncrease();
        }

        return allData;
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportVO>> pageQueryMonthSalesCategoryReportList(QueryMonthSalesReportRequest queryMonthSalesReportRequest) {
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //组装查询组织
        //assembleQueryOrganization(queryMonthSalesReportRequest);
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesCategoryReportQueryRepository.pageQueryMonthSalesCategoryReportSortList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportVO> converterResult = null;
        Result<List<SubtotalViewVO>> viewResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
            viewResult = initSubtotalViewVO();
        }else {
            //填充部门小计，渠道合计，公司总计
            insertTotalRow2(listResult,queryMonthSalesReportRequest);
            //数据格式转换
            converterResult = converterVO(listResult);
            //查询表头的数据统计
            Result<List<SubtotalViewVO>> response = getSubtotalViewData(queryMonthSalesReportRequest,CATEGORY);
            viewResult = response;
        }
        Map<String,Object> ext = new HashMap<>();
        ext.put("statistic",viewResult.getResult());
        String progressValue = DomUtil.getProgressValue(queryMonthSalesReportRequest.getStatisticalDate());
        ext.put("progress", progressValue.substring(0,progressValue.length()-1));
        Result result = Result.listSuccess(converterResult,pageResult.getTotal());
        result.setExt(ext);
        return result;
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportVO>> pageQueryMonthSalesCompanyCategoryReportList(QueryMonthSalesReportRequest queryMonthSalesReportRequest) {
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //组装查询组织
        //assembleQueryOrganization(queryMonthSalesReportRequest);
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesCategoryReportQueryRepository.pageQueryMonthSalesCompanyCategoryReportSortList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportVO> converterResult = null;
        Result<List<SubtotalViewVO>> viewResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
            viewResult = initSubtotalViewVO();
        }else {
            //填充部门小计，渠道合计，公司总计
            insertTotalRow3(listResult,queryMonthSalesReportRequest);
            //数据格式转换
            converterResult = converterComputeVOList(listResult);
            //查询表头的数据统计
            Result<List<SubtotalViewVO>> response = getSubtotalViewData(queryMonthSalesReportRequest,COMPANY_CATEGORY);
            viewResult = response;
        }
        Map<String,Object> ext = new HashMap<>();
        ext.put("statistic",viewResult.getResult());
        String progressValue = DomUtil.getProgressValue(queryMonthSalesReportRequest.getStatisticalDate());
        ext.put("progress", progressValue.substring(0,progressValue.length()-1));
        Result result = Result.listSuccess(converterResult,pageResult.getTotal());
        result.setExt(ext);
        return result;
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportVO>> getMonthSalesAppView(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        List<MonthSalesBasicReportSDO> result = null;
        //业务员
        if(queryMonthSalesReportRequest.getBizType() ==107){
            PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesEmployeeRankReportQueryRepository.pageQueryList(queryMonthSalesReportRequest);
            result = pageResult.getContent();
            //部门
        }else if(queryMonthSalesReportRequest.getBizType() ==106){
            queryMonthSalesReportRequest.setOrgSalesDepartmentIds(queryMonthSalesReportRequest.getOrganizationIds());
            PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesDepartmentRankReportQueryRepository.pageQueryList(queryMonthSalesReportRequest);
            result = pageResult.getContent();
            //渠道
        }else if(queryMonthSalesReportRequest.getBizType() ==105){
            queryMonthSalesReportRequest.setOrgSalesChannelIds(queryMonthSalesReportRequest.getOrganizationIds());
            PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesChannelRankReportQueryRepository.pageQueryList(queryMonthSalesReportRequest);
            result = pageResult.getContent();
            //销售组织
        }else if(queryMonthSalesReportRequest.getBizType() ==104){
            queryMonthSalesReportRequest.setOrgSalesOrganizationIds(queryMonthSalesReportRequest.getOrganizationIds());
            result = monthSalesDepartmentRankReportQueryRepository.statisticalMonthSalesCompanyView(queryMonthSalesReportRequest);
            result.forEach(x->{
                countSalesOrderComplete(x);
            });
            //分子公司
        }else if(queryMonthSalesReportRequest.getBizType() ==103){
            queryMonthSalesReportRequest.setOrgBusinessUnitIds(queryMonthSalesReportRequest.getOrganizationIds());
            result = monthSalesDepartmentRankReportQueryRepository.statisticalMonthSalesCompanyView(queryMonthSalesReportRequest);
            result.forEach(x->{
                countSalesOrderComplete(x);
            });
        }else{
            queryMonthSalesReportRequest.setBizType(103);
            queryMonthSalesReportRequest.setOrgBusinessUnitIds(queryMonthSalesReportRequest.getOrganizationIds());
            result = monthSalesDepartmentRankReportQueryRepository.statisticalMonthSalesCompanyView(queryMonthSalesReportRequest);
            MonthSalesBasicReportSDO sdo = new MonthSalesBasicReportSDO();
            BigDecimal taskCount = new BigDecimal(0);
            BigDecimal beforeMonthMoney = new BigDecimal(0);
            BigDecimal monthMoney = new BigDecimal(0);
            BigDecimal contractMoney = new BigDecimal(0);
            BigDecimal taskCountComplete = new BigDecimal(0);
            BigDecimal beforeMonthMoneyComplete = new BigDecimal(0);
            BigDecimal monthMoneyComplete = new BigDecimal(0);
            for (MonthSalesBasicReportSDO bean : result) {
                taskCount = taskCount.add(new BigDecimal(bean.getTaskCount()));
                beforeMonthMoney = beforeMonthMoney.add(bean.getBeforeMonthMoney());
                monthMoney = monthMoney.add(bean.getMonthMoney());
                contractMoney = contractMoney.add(bean.getContractMoney());
                taskCountComplete = taskCountComplete.add(new BigDecimal(bean.getTaskCountComplete()));
                beforeMonthMoneyComplete = beforeMonthMoneyComplete.add(bean.getBeforeMonthMoneyComplete());
                monthMoneyComplete = monthMoneyComplete.add(bean.getMonthMoneyComplete());
            }
            BigDecimal taskCountCompletePercentage = taskCount.compareTo(new BigDecimal(0))==0?new BigDecimal(0):taskCountComplete.divide(taskCount,4,BigDecimal.ROUND_HALF_UP);
            BigDecimal beforeMonthMoneyCompletetePercentage = beforeMonthMoney.compareTo(new BigDecimal(0))==0?new BigDecimal(0):beforeMonthMoneyComplete.divide(beforeMonthMoney,4,BigDecimal.ROUND_HALF_UP);
            BigDecimal monthMoneyCompletePercentage = monthMoney.compareTo(new BigDecimal(0))==0?new BigDecimal(0):monthMoneyComplete.divide(monthMoney,4,BigDecimal.ROUND_HALF_UP);
            BigDecimal contractMoneyCompletePercentage = contractMoney.compareTo(new BigDecimal(0))==0?new BigDecimal(0):monthMoneyComplete.divide(contractMoney,4,BigDecimal.ROUND_HALF_UP);
            sdo.setTaskCount(taskCount.longValue());
            sdo.setBeforeMonthMoney(beforeMonthMoney);
            sdo.setMonthMoney(monthMoney);
            sdo.setContractMoney(contractMoney);
            sdo.setTaskCountComplete(taskCountComplete.longValue());
            sdo.setBeforeMonthMoneyComplete(beforeMonthMoneyComplete);
            sdo.setMonthMoneyComplete(monthMoneyComplete);
            sdo.setContractMoneyComplete(monthMoneyComplete);
            sdo.setTaskCountCompletePercentage(taskCountCompletePercentage);
            sdo.setBeforeMonthMoneyCompletePercentage(beforeMonthMoneyCompletetePercentage);
            sdo.setMonthMoneyCompletePercentage(monthMoneyCompletePercentage);
            sdo.setContractMoneyCompletePercentage(contractMoneyCompletePercentage);
            result = Lists.newArrayList(sdo);
        }
        List<MonthSalesProgressReportVO> converterResult = converterVO(result);
        return Result.listSuccess(converterResult,converterResult.size());
    }

    @Override
    @FacadeInvoker
    public Result<List<RankViewVO>> getMonthSalesViewBySalesRank(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        if(CollectionUtils.isEmpty(queryMonthSalesReportRequest.getOrgBusinessUnitIds())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-002"));
        }
        List<RankViewVO> listVO = new ArrayList<>();
        if(Objects.equals(1,queryMonthSalesReportRequest.getBizType())){
            //销量达成客户排名
            listVO.add(getSalesRank(CUSTOMER_RANK,queryMonthSalesReportRequest));
        }else if(Objects.equals(2,queryMonthSalesReportRequest.getBizType())){
            //销量达成货品排名
            listVO.add(getSalesRank(SCITEM_RANK,queryMonthSalesReportRequest));
        }else if(Objects.equals(3,queryMonthSalesReportRequest.getBizType())){
            //销量达成品类排名
            listVO.add(getSalesRank(CATEGORY_RANK,queryMonthSalesReportRequest));
        }else{
            //销量达成客户排名
            listVO.add(getSalesRank(CUSTOMER_RANK,queryMonthSalesReportRequest));
            //销量达成货品排名
            listVO.add(getSalesRank(SCITEM_RANK,queryMonthSalesReportRequest));
            //销量达成品类排名
            listVO.add(getSalesRank(CATEGORY_RANK,queryMonthSalesReportRequest));
        }
        return Result.listSuccess(listVO,listVO.size());
    }

    private RankViewVO getSalesRank(String groupBy,QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        queryMonthSalesReportRequest.setGroupBy(groupBy);
        List<MonthSalesBasicReportSDO> sortList = monthSalesBasicReportQueryRepository.statisticalSalesRankQuery(queryMonthSalesReportRequest);
        sortList = sortList.stream().filter(x->x.getMonthMoneyComplete().compareTo(BigDecimal.ZERO)!=0).collect(Collectors.toList());
        RankViewVO vo = new RankViewVO();
        if(CUSTOMER_RANK.equals(groupBy)){
            vo.setTitle("销量达成TOP10客户排名");
            vo.setTab(RankTab.builder().sortNo("排序").label("客户名称").quantity("当月任务金额已达成-折后(万元)").build());
        }else if(SCITEM_RANK.equals(groupBy)){
            vo.setTitle("销量达成TOP10货品排名");
            vo.setTab(RankTab.builder().sortNo("排序").label("货品名称").quantity("当月任务金额已达成-折后(万元)").build());
        }else if(CATEGORY_RANK.equals(groupBy)){
            vo.setTitle("销量达成品类排名");
            vo.setTab(RankTab.builder().sortNo("排序").label("品类名称").quantity("当月任务金额已达成-折后(万元)").build());
        }else{
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-004"));
        }
        List<RankData> data = new ArrayList<>();
        PageRecordUtil pageUtil = new PageRecordUtil();
        pageUtil.resetPageParam();
        BigDecimal den = new BigDecimal(0);
        for (int i = 0; i < sortList.size(); i++) {
            MonthSalesBasicReportSDO sdo = sortList.get(i);
            RankData v = new RankData();
            v.setLabel(CUSTOMER_RANK.equals(groupBy)?sdo.getCustomerName():SCITEM_RANK.equals(groupBy)?sdo.getScItemName():sdo.getScItemRootCategoryName());
            if(CATEGORY_RANK.equals(groupBy)&&StringUtil.isBlank(v.getLabel())){
                v.setLabel("未知类目");
            }
            String monthMoneyComplete = SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyComplete());
            v.setQuantity(monthMoneyComplete);
            //折后金额达成百分比
            BigDecimal monthMoneyCompletePercentage = sdo.getMonthMoney().compareTo(BigDecimal.ZERO) == 0?BigDecimal.ZERO:sdo.getMonthMoneyComplete().divide(sdo.getMonthMoney(),4,RoundingMode.HALF_UP);
            String completePercent = DomUtil.percentFormat(monthMoneyCompletePercentage);
            //v.setMonthMoneyCompletePercentage(completePercent);
            //排序号
            //v.setSortNo(pageUtil.getLastMoney().compareTo(sdo.getMonthMoneyComplete()) == 0?pageUtil.getLastSameSortNo():pageUtil.getNewSortNoAndRecordLastSortNo());
            v.setSortNo(pageUtil.getSortNo());
            //排名百分比
            if(i == 0){
                den = sdo.getMonthMoneyComplete();
                v.setProgress(den.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:new BigDecimal(100));
            }else{
                BigDecimal percent = den.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:sdo.getMonthMoneyComplete().divide(den,4,RoundingMode.HALF_UP).multiply(new BigDecimal(100));
                percent = percent.setScale(2);
                v.setProgress(percent);
            }
            v.setTipsOne("当月任务金额已达成(折后)  "+monthMoneyComplete);
            v.setTipsTwo("达成百分比  "+completePercent);
            data.add(v);
            //pageUtil.recordlastMoney(sdo.getMonthMoneyComplete());
            pageUtil.sortNoIncrease();
        }
        vo.setData(data);
        return vo;
    }

    @Override
    @FacadeInvoker
    public Result<MonthSalesProgressReportViewListVO> getMonthSalesViewByDaySales(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        if(CollectionUtils.isEmpty(queryMonthSalesReportRequest.getOrgBusinessUnitIds())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-002"));
        }
        MonthSalesProgressReportViewListVO vo = new MonthSalesProgressReportViewListVO();
        Date statisticalDate = DateUtils.parse(queryMonthSalesReportRequest.getStatisticalDate());
        //本月日销量
        queryMonthSalesReportRequest.setBeginDate(DomUtil.getStartOfMonth(statisticalDate));
        queryMonthSalesReportRequest.setEndDate(queryMonthSalesReportRequest.getStatisticalDate());
        List<MonthSalesBasicReportSDO> thisMonthResult = monthSalesDepartmentRankReportQueryRepository.statisticalDaySalesQuery(queryMonthSalesReportRequest);
        vo.setCurrentMonth(countDaySalesAmountList(thisMonthResult,"当月任务金额已完成-折后"));
        //上月日销量
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(statisticalDate);
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        queryMonthSalesReportRequest.setBeginDate(format.format(calendar.getTime()));
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        queryMonthSalesReportRequest.setEndDate(format.format(calendar.getTime()));
        List<MonthSalesBasicReportSDO> lastMonthResult = monthSalesDepartmentRankReportQueryRepository.statisticalDaySalesQuery(queryMonthSalesReportRequest);
        vo.setLastMonth(countDaySalesAmountList(lastMonthResult,"上月任务金额已完成-折后"));
        vo.setStatisticalDate(queryMonthSalesReportRequest.getStatisticalDate());
        return Result.success(vo);
    }

    private List<MonthSalesProgressReportViewVO> countDaySalesAmountList(List<MonthSalesBasicReportSDO> result,String name){
        Map<String,MonthSalesBasicReportSDO> resultMap = result.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getStatisticalDate, Function.identity(),(v1,v2)->v1));
        List<MonthSalesProgressReportViewVO> data = new ArrayList<>();
        for(MonthSalesBasicReportSDO sdo : result){
            MonthSalesProgressReportViewVO v = new MonthSalesProgressReportViewVO();
            Date date = DateUtils.parse(sdo.getStatisticalDate());
            MonthSalesBasicReportSDO tmp = resultMap.get(DomUtil.getYesterdayByDate(date));
            BigDecimal daySalesAmount = tmp!=null?sdo.getMonthMoneyComplete().subtract(tmp.getMonthMoneyComplete()):sdo.getMonthMoneyComplete();
            v.setName(name);
            //v.setDay(String.valueOf(getDay(date)));
            v.setStatisticalDate(sdo.getStatisticalDate());
            v.setNum(daySalesAmount);
            v.setValue(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,daySalesAmount)+"万");
            //v.setIntValue(daySalesAmount.divide(new BigDecimal(SubtotalViewVOUtil.TEN_THOUSAND),2,BigDecimal.ROUND_HALF_UP).intValue());
//            DecimalFormat df = new DecimalFormat("###,##0.00");
//            v.setFormatValue(df.format(daySalesAmount));
            data.add(v);
        }
        //data = data.stream().sorted((s1,s2) -> s2.getDay().compareTo(s1.getDay())).collect(Collectors.toList());
        return data;
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportViewListVO>> getMonthSalesViewByDepartment(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        if(CollectionUtils.isEmpty(queryMonthSalesReportRequest.getOrgBusinessUnitIds()) && StringUtil.isBlank(queryMonthSalesReportRequest.getOrgSalesChannelId())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-002"));
        }
        //统计时间+分子公司 查这个月的月度销售进度
        queryMonthSalesReportRequest.setBizType(OrganizationTypeEnum.SALES_DEPARTMENT.getCode());
        List<MonthSalesBasicReportSDO> thisMonthMonthSalesResult = monthSalesDepartmentRankReportQueryRepository.statisticalMonthSalesCompanyView(queryMonthSalesReportRequest);
        if(CollectionUtils.isEmpty(thisMonthMonthSalesResult)){
            return Result.listSuccess(new ArrayList<>(),0);
        }

        Map<String,List<MonthSalesBasicReportSDO>> channelGroupMap = thisMonthMonthSalesResult.stream().collect(Collectors.groupingBy(MonthSalesBasicReportSDO::getOrgSalesChannelId));
        List<MonthSalesProgressReportViewListVO> listVO = new ArrayList<>();
        PageRecordUtil pageUtil = new PageRecordUtil();
        for (Map.Entry<String, List<MonthSalesBasicReportSDO>> entry: channelGroupMap.entrySet()){
            List<MonthSalesBasicReportSDO> list = entry.getValue();
            list = list.stream().sorted((s1,s2) -> s2.getMonthMoneyComplete().compareTo(s1.getMonthMoneyComplete())).collect(Collectors.toList());
            pageUtil.resetPageParam();
            List<MonthSalesProgressReportViewVO> data = new ArrayList<>();
            BigDecimal den = new BigDecimal(0);
            for (int i = 0; i < list.size(); i++) {
                MonthSalesProgressReportViewVO v = converterViewVO(list.get(i));
//                v.setMonthMoneyComplete(v.getMonthMoneyComplete()+"万");
                v.setSortNo(pageUtil.getLastMoney().compareTo(list.get(i).getMonthMoneyComplete()) == 0?pageUtil.getLastSameSortNo():pageUtil.getNewSortNoAndRecordLastSortNo());
                if(i == 0){
                    den = list.get(i).getMonthMoneyComplete();
                    v.setRankPercentage(den.compareTo(new BigDecimal(0))==0?new BigDecimal(0):new BigDecimal(100));
                }else{
                    BigDecimal percent = den.compareTo(new BigDecimal(0))==0?new BigDecimal(0):list.get(i).getMonthMoneyComplete().divide(den,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                    percent = percent.setScale(2);
                    v.setRankPercentage(percent);
                }
                data.add(v);
                pageUtil.recordlastMoney(list.get(i).getMonthMoneyComplete());
                pageUtil.sortNoIncrease();
            }
            MonthSalesProgressReportViewListVO vo = new MonthSalesProgressReportViewListVO();
            vo.setOrgSalesChannelId(list.get(0).getOrgSalesChannelId());
            vo.setOrgSalesChannelName(list.get(0).getOrgSalesChannelName());
            vo.setData(data);
            listVO.add(vo);
        }
        return Result.listSuccess(listVO,listVO.size());
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportViewVO>> getMonthSalesViewByChannel(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        if(CollectionUtils.isEmpty(queryMonthSalesReportRequest.getOrgBusinessUnitIds())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-002"));
        }
        //统计时间+分子公司 查这个月的月度销售进度
        queryMonthSalesReportRequest.setBizType(OrganizationTypeEnum.SALES_CHANNEL.getCode());
        List<MonthSalesBasicReportSDO> thisMonthMonthSalesResult = monthSalesDepartmentRankReportQueryRepository.statisticalMonthSalesCompanyView(queryMonthSalesReportRequest);
        if(CollectionUtils.isEmpty(thisMonthMonthSalesResult)){
            return Result.listSuccess(new ArrayList<>(),0);
        }

        List<MonthSalesProgressReportViewVO> converterResult = converterViewVOList(thisMonthMonthSalesResult);
        return Result.listSuccess(converterResult,converterResult.size());
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportViewVO>> getMonthSalesViewByCompany(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        if(CollectionUtils.isEmpty(queryMonthSalesReportRequest.getOrgBusinessUnitIds())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-002"));
        }
        if(queryMonthSalesReportRequest.getOrgBusinessUnitIds().size()>1){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-003"));
        }
        //统计时间+公司列表 查这个月的月度销售进度
        queryMonthSalesReportRequest.setBizType(OrganizationTypeEnum.COMPANY.getCode());
        List<MonthSalesBasicReportSDO> thisMonthMonthSalesResult = monthSalesDepartmentRankReportQueryRepository.statisticalMonthSalesCompanyView(queryMonthSalesReportRequest);
        if(CollectionUtils.isEmpty(thisMonthMonthSalesResult)){
            return Result.listSuccess(new ArrayList<>(),0);
        }

        //根据入参的统计日期得到上个月的时间戳
        QueryMonthSalesReportRequest request = new QueryMonthSalesReportRequest();
//        request.setPlanMonth(getLastMonthTimestamp(queryMonthSalesReportRequest.getStatisticalDate()));
//        request.setDataMark(DataMarkEnum.MONTH_FINAL_DATA.getCode());
        request.setStatisticalDate(DomUtil.getLastDayLastMonth(DateUtils.parse(queryMonthSalesReportRequest.getStatisticalDate())));
        request.setBizType(OrganizationTypeEnum.COMPANY.getCode());
        request.setOrgBusinessUnitIds(queryMonthSalesReportRequest.getOrgBusinessUnitIds());
        //上月时间戳+dataMark+公司列表  查上个月的月度销售进度
        List<MonthSalesBasicReportSDO> lastMonthMonthSalesResult = monthSalesDepartmentRankReportQueryRepository.statisticalMonthSalesCompanyView(request);
        Map<String,MonthSalesBasicReportSDO> lastMonthMonthSalesMap = lastMonthMonthSalesResult.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgBusinessUnitId, Function.identity(),(v1, v2)->v1));

        //CRM公司合同量
        Date statDate = DateUtils.parse(queryMonthSalesReportRequest.getStatisticalDate());
        BatchQueryContractQuantityRequest contractQueryRequest = new BatchQueryContractQuantityRequest();
        contractQueryRequest.setOrganizationIds(queryMonthSalesReportRequest.getOrgBusinessUnitIds());
        contractQueryRequest.setType("103");
        contractQueryRequest.setContractYear(DomUtil.getYear(statDate));
        contractQueryRequest.setDataSource(ContractDataSourceEnum.CRM.getCode());
        List<Contract> companyContractList = planContractQuantityRepository.batchQueryContractByOrganiztion(contractQueryRequest);
        Map<String,Contract> companyContractMap = Nullable.stream(companyContractList).collect(Collectors.toMap(Contract::getOrgBusinessUnitCode, Function.identity(),(v1, v2)->v1));

        //计算较上月增长
        List<MonthSalesProgressReportViewVO> converterResult = converterViewVOListCompany(thisMonthMonthSalesResult,lastMonthMonthSalesMap,companyContractMap,statDate);
        //计算新品占比
        if("1".equals(queryMonthSalesReportRequest.getMark())){
            MonthSalesProgressReportViewVO sdo = converterResult.get(0);
            List<MonthSalesBasicReportSDO> thisMonthNewScItemStat = monthSalesBasicReportQueryRepository.statisticalScItemMarkQuery(queryMonthSalesReportRequest);
            if(CollectionUtils.isNotEmpty(thisMonthNewScItemStat)){
                MonthSalesBasicReportSDO tmp = thisMonthNewScItemStat.get(0);
                BigDecimal contractMoney = tmp.getContractMoney();
                BigDecimal monthMoneyComplete = tmp.getMonthMoneyComplete();
                //折后合同金额达成百分比
                BigDecimal contractMoneyCompletePercentage = contractMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):monthMoneyComplete.divide(contractMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                contractMoneyCompletePercentage = contractMoneyCompletePercentage.setScale(2);
                sdo.setNewContractMoney(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,contractMoney));
                sdo.setNewContractMoneyComplete(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,monthMoneyComplete));
                sdo.setNewContractMoneyCompletePercentage(contractMoneyCompletePercentage.toString());
                sdo.setNewContractMoneyRemain(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,tmp.getContractMoneyRemain()));
                //合同金额较上月
                List<MonthSalesBasicReportSDO> lastMonthNewScItemStat = monthSalesBasicReportQueryRepository.statisticalScItemMarkQuery(request);
                BigDecimal lastMonthMoney = new BigDecimal(0);
                if(CollectionUtils.isNotEmpty(lastMonthNewScItemStat) && lastMonthNewScItemStat.get(0).getContractMoney()!=null){
                    lastMonthMoney = lastMonthNewScItemStat.get(0).getContractMoney();
                }
                if(lastMonthMoney.compareTo(BigDecimal.ZERO) == 0){
                    sdo.setNewContractMoneyIncrease("-");
                }else{
                    BigDecimal contractMoneyIncrease = (contractMoney.subtract(lastMonthMoney)).divide(lastMonthMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                    contractMoneyIncrease = contractMoneyIncrease.setScale(2);
                    sdo.setNewContractMoneyIncrease(contractMoneyIncrease.toString());
                }

                if(thisMonthMonthSalesResult.get(0).getMonthMoneyComplete().compareTo(new BigDecimal(0)) == 0){
                    sdo.setNewContractMoneyOccupy("-");
                }else{
                    BigDecimal occupy = monthMoneyComplete.divide(thisMonthMonthSalesResult.get(0).getMonthMoneyComplete(),4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                    occupy = occupy.setScale(2);
                    sdo.setNewContractMoneyOccupy(occupy.toString());
                }
            }else{
                sdo.setNewContractMoney("-");
                sdo.setNewContractMoneyComplete("-");
                sdo.setNewContractMoneyCompletePercentage("-");
                sdo.setNewContractMoneyRemain("-");
                sdo.setNewContractMoneyIncrease("-");
                sdo.setNewContractMoneyOccupy("-");
            }
        }
        //List<MonthSalesProgressReportViewVO> sortResult = sortListByOrgIds(queryMonthSalesReportRequest.getOrganizationIds(),converterResult);
        return Result.listSuccess(converterResult,converterResult.size());
    }

    @Override
    @FacadeInvoker
    public Result<MonthSalesProgressReportAppViewVO> getMonthSalesAppViewByCompany(QueryMonthSalesReportRequest queryMonthSalesReportRequest) {
        MonthSalesProgressReportAppViewVO result = new MonthSalesProgressReportAppViewVO();
        queryMonthSalesReportRequest.setMark("1");
        //分子公司
        Result<List<MonthSalesProgressReportViewVO>> companyResult = getMonthSalesViewByCompany(queryMonthSalesReportRequest);
        if(CollectionUtils.isEmpty(companyResult.getResult())){
            return Result.success(null);
        }
        result.setCompanySalesProgress(companyResult.getResult().get(0));
        //渠道
        Result<List<MonthSalesProgressReportViewVO>> channelResult = getMonthSalesViewByChannel(queryMonthSalesReportRequest);
        Map<String,List<Map<String,Object>>> convertMap = convertAppChannelResult(channelResult.getResult());
        result.setChannelSalesProgress(convertMap);
        //部门
        Result<List<MonthSalesProgressReportViewListVO>> departmentResult = getMonthSalesViewByDepartment(queryMonthSalesReportRequest);
        result.setDepartmentSalesProgress(convertAppDepartmentResult(departmentResult.getResult()));
        //销量达成排名
        Result<List<MonthSalesProgressReportViewListVO>> customerSalesRankResult = getMonthSalesRankApp(queryMonthSalesReportRequest);
        result.setMonthSalesRank(convertAppMonthSalesRankResult(customerSalesRankResult.getResult().get(0)));
        //月度日销量
        Result<MonthSalesProgressReportViewListVO> monthDaySales = getMonthSalesViewByDaySales(queryMonthSalesReportRequest);
        result.setMonthDaySales(convertAppMonthDaySalesResult(monthDaySales.getResult()));
        return Result.success(result);
    }

    @FacadeInvoker
    private Result<List<MonthSalesProgressReportViewListVO>> getMonthSalesRankApp(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        if(CollectionUtils.isEmpty(queryMonthSalesReportRequest.getOrgBusinessUnitIds())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-002"));
        }
        List<MonthSalesProgressReportViewListVO> listVO = new ArrayList<>();
        MonthSalesProgressReportViewListVO vo = new MonthSalesProgressReportViewListVO();
        if(Objects.equals(1,queryMonthSalesReportRequest.getBizType())){
            //销量达成客户排名
            vo.setCustomerRankList(countSalesRank(CUSTOMER_RANK,queryMonthSalesReportRequest));
        }else if(Objects.equals(2,queryMonthSalesReportRequest.getBizType())){
            //销量达成货品排名
            vo.setScItemRankList(countSalesRank(SCITEM_RANK,queryMonthSalesReportRequest));
        }else if(Objects.equals(3,queryMonthSalesReportRequest.getBizType())){
            //销量达成品类排名
            vo.setCategoryRankList(countSalesRank(CATEGORY_RANK,queryMonthSalesReportRequest));
        }else{
            //销量达成客户排名
            vo.setCustomerRankList(countSalesRank(CUSTOMER_RANK,queryMonthSalesReportRequest));
            //销量达成货品排名
            vo.setScItemRankList(countSalesRank(SCITEM_RANK,queryMonthSalesReportRequest));
            //销量达成品类排名
            vo.setCategoryRankList(countSalesRank(CATEGORY_RANK,queryMonthSalesReportRequest));
        }
        listVO.add(vo);
        return Result.listSuccess(listVO,listVO.size());
    }

    private List<MonthSalesProgressReportViewVO> countSalesRank(String groupBy,QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        queryMonthSalesReportRequest.setGroupBy(groupBy);
        List<MonthSalesBasicReportSDO> sortList = monthSalesBasicReportQueryRepository.statisticalSalesRankQuery(queryMonthSalesReportRequest);
        sortList = sortList.stream().filter(x->x.getMonthMoneyComplete().compareTo(BigDecimal.ZERO)!=0).collect(Collectors.toList());
        List<MonthSalesProgressReportViewVO> data = new ArrayList<>();
        PageRecordUtil pageUtil = new PageRecordUtil();
        pageUtil.resetPageParam();
        BigDecimal den = new BigDecimal(0);
        for (int i = 0; i < sortList.size(); i++) {
            MonthSalesBasicReportSDO sdo = sortList.get(i);
            MonthSalesProgressReportViewVO v = new MonthSalesProgressReportViewVO();
            v.setName(CUSTOMER_RANK.equals(groupBy)?sdo.getCustomerName():SCITEM_RANK.equals(groupBy)?sdo.getScItemName():sdo.getScItemRootCategoryName());
            String monthMoneyComplete = SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyComplete());
            v.setMonthMoneyComplete(monthMoneyComplete);
            //折后金额达成百分比
            BigDecimal monthMoneyCompletePercentage = sdo.getMonthMoney().compareTo(BigDecimal.ZERO) == 0?BigDecimal.ZERO:sdo.getMonthMoneyComplete().divide(sdo.getMonthMoney(),4,RoundingMode.HALF_UP);
            String completePercent = DomUtil.percentFormat(monthMoneyCompletePercentage);
            v.setMonthMoneyCompletePercentage(completePercent);
            //排序号
            //v.setSortNo(pageUtil.getLastMoney().compareTo(sdo.getMonthMoneyComplete()) == 0?pageUtil.getLastSameSortNo():pageUtil.getNewSortNoAndRecordLastSortNo());
            v.setSortNo(pageUtil.getSortNo());
            //排名百分比
            if(i == 0){
                den = sdo.getMonthMoneyComplete();
                v.setRankPercentage(den.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:new BigDecimal(100));
            }else{
                BigDecimal percent = den.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:sdo.getMonthMoneyComplete().divide(den,4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
                percent = percent.setScale(2);
                v.setRankPercentage(percent);
            }
            v.setValue("当月任务金额已达成(折后)  "+monthMoneyComplete);
            v.setFormatValue("达成百分比  "+completePercent);
            data.add(v);
            //pageUtil.recordlastMoney(sdo.getMonthMoneyComplete());
            pageUtil.sortNoIncrease();
        }
        return data;
    }

    private RankAppComponent convertAppDepartmentResult(List<MonthSalesProgressReportViewListVO> list){
        RankAppComponent component = new RankAppComponent();
        component.setTopName("部门销售达成排名");
        List<RankAppComponentData> dataList = new ArrayList<>();
        for (MonthSalesProgressReportViewListVO sdo : list) {
            RankAppComponentData data = new RankAppComponentData();
            data.setTabName(sdo.getOrgSalesChannelName());
            data.setTabId(sdo.getOrgSalesChannelId());
            data.setTopTitles(Lists.newArrayList("排名","部门名称","当月任务金额已达成-折后(万元)"));
            List<RankAppComponentContent> contentList = sdo.getData().stream().map(x ->{
                RankAppComponentContent content = new RankAppComponentContent();
                content.setName(x.getOrgSalesDepartmentName());
                content.setNum(x.getMonthMoneyComplete());
                content.setRatio(x.getRankPercentage().toString());
                content.setSortNo(x.getSortNo());
                List<RankAppComponentChildren> childrenList = new ArrayList<>();
                RankAppComponentChildren children1 = new RankAppComponentChildren();
                children1.setTitle("当月合同金额-折后(万元)");
                children1.setCount(x.getContractMoney());
                //children1.setRatio(x.getContractMoneyCompletePercentage());
                childrenList.add(children1);
                RankAppComponentChildren children2 = new RankAppComponentChildren();
                children2.setTitle("当月任务数量(万件)");
                children2.setCount(x.getTaskCount());
                children2.setRatio(x.getTaskCountCompletePercentage());
                childrenList.add(children2);
                RankAppComponentChildren children3 = new RankAppComponentChildren();
                children3.setTitle("当月任务金额-折前(万元)");
                children3.setCount(x.getBeforeMonthMoney());
                children3.setRatio(x.getBeforeMonthMoneyCompletePercentage());
                childrenList.add(children3);
                RankAppComponentChildren children4 = new RankAppComponentChildren();
                children4.setTitle("当月任务金额-折后(万元)");
                children4.setCount(x.getMonthMoney());
                children4.setRatio(x.getMonthMoneyCompletePercentage());
                childrenList.add(children4);
                content.setChildren(childrenList);
                return content;
            }).collect(Collectors.toList());
            data.setContent(contentList);
            dataList.add(data);
        }
        component.setTopData(dataList);
        return component;
    }

    private RankAppComponent convertAppMonthSalesRankResult(MonthSalesProgressReportViewListVO sdo){
        RankAppComponent component = new RankAppComponent();
        component.setTopName("销售达成排名");
        List<RankAppComponentData> dataList = new ArrayList<>();
        RankAppComponentData customerData = new RankAppComponentData();
        customerData.setTabName("客户排名");
        customerData.setTabId("1");
        customerData.setTopTitles(Lists.newArrayList("排名","客户名称","当月任务金额已达成-折后(万元)"));
        List<RankAppComponentContent> customerContentList = sdo.getCustomerRankList().stream().map(x -> {
            RankAppComponentContent content = new RankAppComponentContent();
            content.setName(x.getName());
            content.setNum(x.getMonthMoneyComplete());
            content.setRatio(x.getRankPercentage().toString());
            content.setSortNo(x.getSortNo());
            RankAppComponentChildren children1 = new RankAppComponentChildren();
            children1.setTitle("当月任务金额已达成-折后(万元)");
            children1.setCount(x.getMonthMoneyComplete());
            RankAppComponentChildren children2 = new RankAppComponentChildren();
            children2.setTitle("达成百分比");
            children2.setCount(x.getMonthMoneyCompletePercentage());
            content.setChildren(Lists.newArrayList(children1,children2));
            return content;
        }).collect(Collectors.toList());
        customerData.setContent(customerContentList);
        dataList.add(customerData);

        RankAppComponentData scItemData = new RankAppComponentData();
        scItemData.setTabName("货品排名");
        scItemData.setTabId("2");
        scItemData.setTopTitles(Lists.newArrayList("排名","货品名称","当月任务金额已达成-折后(万元)"));
        List<RankAppComponentContent> scItemContentList = sdo.getScItemRankList().stream().map(x -> {
            RankAppComponentContent content = new RankAppComponentContent();
            content.setName(x.getName());
            content.setNum(x.getMonthMoneyComplete());
            content.setRatio(x.getRankPercentage().toString());
            content.setSortNo(x.getSortNo());
            RankAppComponentChildren children1 = new RankAppComponentChildren();
            children1.setTitle("当月任务金额已达成-折后(万元)");
            children1.setCount(x.getMonthMoneyComplete());
            RankAppComponentChildren children2 = new RankAppComponentChildren();
            children2.setTitle("达成百分比");
            children2.setCount(x.getMonthMoneyCompletePercentage());
            content.setChildren(Lists.newArrayList(children1,children2));
            return content;
        }).collect(Collectors.toList());
        scItemData.setContent(scItemContentList);
        dataList.add(scItemData);

        RankAppComponentData categoryData = new RankAppComponentData();
        categoryData.setTabName("品类排名");
        categoryData.setTabId("3");
        categoryData.setTopTitles(Lists.newArrayList("排名","品类名称","当月任务金额已达成-折后(万元)"));
        List<RankAppComponentContent> categoryContentList = sdo.getCategoryRankList().stream().map(x -> {
            RankAppComponentContent content = new RankAppComponentContent();
            content.setName(StringUtils.isNotBlank(x.getName())?x.getName():"未知类目");
            content.setNum(x.getMonthMoneyComplete());
            content.setRatio(x.getRankPercentage().toString());
            content.setSortNo(x.getSortNo());
            RankAppComponentChildren children1 = new RankAppComponentChildren();
            children1.setTitle("当月任务金额已达成-折后(万元)");
            children1.setCount(x.getMonthMoneyComplete());
            RankAppComponentChildren children2 = new RankAppComponentChildren();
            children2.setTitle("达成百分比");
            children2.setCount(x.getMonthMoneyCompletePercentage());
            content.setChildren(Lists.newArrayList(children1,children2));
            return content;
        }).collect(Collectors.toList());
        categoryData.setContent(categoryContentList);
        dataList.add(categoryData);

        component.setTopData(dataList);
        return component;
    }

    private Map<String,List<Map<String,Object>>> convertAppChannelResult(List<MonthSalesProgressReportViewVO> list){
        Map<String,List<Map<String,Object>>> map = new HashMap();
        List<Map<String,Object>> tableConfig = new ArrayList<>();
        Map<String,Object> aaa = new HashMap<>();
        aaa.put("title","渠道");
        aaa.put("dataKey","orgSalesChannelName");
        aaa.put("width","250");
        tableConfig.add(aaa);
        Map<String,Object> bbb = new HashMap<>();
        bbb.put("title","当月合同金额-折后(万元)");
        bbb.put("dataKey","contractMoney");
        bbb.put("width","400");
        tableConfig.add(bbb);
        Map<String,Object> ccc = new HashMap<>();
        ccc.put("title","当月任务数量(万件)");
        ccc.put("dataKey","taskCount");
        ccc.put("width","400");
        tableConfig.add(ccc);
        Map<String,Object> ddd = new HashMap<>();
        ddd.put("title","当月任务金额-折前(万元)");
        ddd.put("dataKey","beforeMonthMoney");
        ddd.put("width","400");
        tableConfig.add(ddd);
        Map<String,Object> eee = new HashMap<>();
        eee.put("title","当月任务金额-折后(万元)");
        eee.put("dataKey","monthMoney");
        eee.put("width","400");
        tableConfig.add(eee);
        map.put("tableConfig",tableConfig);
        List<Map<String,Object>> dataSource = new ArrayList();
        if(CollectionUtils.isEmpty(list)){
            map.put("dataSource",dataSource);
            return map;
        }
        for (MonthSalesProgressReportViewVO o :list) {
            Map<String,Object> tmp = new HashMap<>();
            tmp.put("orgSalesChannelName",o.getOrgSalesChannelName());
            Map<String,String> contractMoney = new HashMap<>();
            contractMoney.put("num",o.getContractMoney());
            contractMoney.put("ratio",o.getContractMoneyCompletePercentage());
            tmp.put("contractMoney",contractMoney);
            Map<String,String> taskCount = new HashMap<>();
            taskCount.put("num",o.getTaskCount());
            taskCount.put("ratio",o.getTaskCountCompletePercentage());
            tmp.put("taskCount",taskCount);
            Map<String,String> beforeMonthMoney = new HashMap<>();
            beforeMonthMoney.put("num",o.getBeforeMonthMoney());
            beforeMonthMoney.put("ratio",o.getBeforeMonthMoneyCompletePercentage());
            tmp.put("beforeMonthMoney",beforeMonthMoney);
            Map<String,String> monthMoney = new HashMap<>();
            monthMoney.put("num",o.getMonthMoney());
            monthMoney.put("ratio",o.getMonthMoneyCompletePercentage());
            tmp.put("monthMoney",monthMoney);
            dataSource.add(tmp);
        }
        map.put("dataSource",dataSource);
        return map;
    }

    private List<MonthSalesProgressReportViewVO> convertAppMonthDaySalesResult(MonthSalesProgressReportViewListVO viewListVO){
        List<MonthSalesProgressReportViewVO> currentMonthList = viewListVO.getCurrentMonth().stream().map(x ->{
            MonthSalesProgressReportViewVO bean = new MonthSalesProgressReportViewVO();
            bean.setNum(x.getNum());
            bean.setName("currentMonth");
            bean.setDay(String.valueOf(getDay(DateUtils.parse(x.getStatisticalDate()))));
            //bean.setDay(x.getStatisticalDate().substring(8,10));
            bean.setValue(x.getValue());
            return bean;
        }).collect(Collectors.toList());
        List<MonthSalesProgressReportViewVO> lastMonthList = viewListVO.getLastMonth().stream().map(x ->{
            MonthSalesProgressReportViewVO bean = new MonthSalesProgressReportViewVO();
            bean.setNum(x.getNum());
            bean.setName("lastMonth");
            bean.setDay(String.valueOf(getDay(DateUtils.parse(x.getStatisticalDate()))));
            //bean.setDay(x.getStatisticalDate().substring(8,10));
            bean.setValue(x.getValue());
            return bean;
        }).collect(Collectors.toList());
        currentMonthList.addAll(lastMonthList);
        return currentMonthList;
    }

    private List<MonthSalesProgressReportViewVO> sortListByOrgIds(List<String> ids, List<MonthSalesProgressReportViewVO> list){
        Map<String, MonthSalesProgressReportViewVO> viewVOMap =  list.stream().collect(Collectors.toMap(MonthSalesProgressReportViewVO::getOrganizationId, Function.identity(),(v1,v2)->v1));
        List<MonthSalesProgressReportViewVO> sortList = new ArrayList<>();
        ids.forEach( x ->{
            if(viewVOMap.get(x)!=null){
                sortList.add(viewVOMap.get(x));
            }
        });
        return sortList;
    }

    private Result<List<SubtotalViewVO>> getSubtotalViewData(QueryMonthSalesReportRequest queryRequest,String queryType){
        QueryMonthSalesReportRequest request = QueryMonthSalesReportRequest.builder()
                .orgBusinessUnitIds(queryRequest.getOrgBusinessUnitIds())
                .orgSalesChannelIds(queryRequest.getOrgSalesChannelIds())
                .orgSalesOrganizationIds(queryRequest.getOrgSalesOrganizationIds())
                .orgSalesDepartmentIds(queryRequest.getOrgSalesDepartmentIds())
                .manageEmployeeIds(queryRequest.getManageEmployeeIds())
                .customerCodes(queryRequest.getCustomerCodes())
                .customerAddressCodes(queryRequest.getCustomerAddressCodes())
                .customerAddressCode(queryRequest.getCustomerAddressCode())
                .scItemCategoryName(queryRequest.getScItemCategoryName())
                .scItemRootCategoryIds(queryRequest.getScItemRootCategoryIds())
                .scItemLeafCategoryIds(queryRequest.getScItemLeafCategoryIds())
                .scItemCategoryIds(queryRequest.getScItemCategoryIds())
                .scItemCodes(queryRequest.getScItemCodes())
                .scItemOutCode(queryRequest.getScItemOutCode())
                .bizType(queryRequest.getBizType())
                .channelManageEmployeeIds(queryRequest.getChannelManageEmployeeIds())
                .departmentManageEmployeeIds(queryRequest.getDepartmentManageEmployeeIds())
                .departmentSimpleName(queryRequest.getDepartmentSimpleName())
                .statisticalDate(queryRequest.getStatisticalDate())
                .build();
        request.setGroupBy(GROUPBY_DATE);
        List<MonthSalesBasicReportSDO> response = null;
        switch (queryType){
            case CHANNEL_RANK:
                response = monthSalesChannelRankReportQueryRepository.statisticalQuery(request);
                break;
            case DEPARTMENT_RANK:
                response = monthSalesDepartmentRankReportQueryRepository.statisticalQuery(request);
                break;
            case EMPLOYEE_RANK:
                response = monthSalesEmployeeRankReportQueryRepository.statisticalQuery(request);
                break;
            case CATEGORY:
                response = monthSalesCategoryReportQueryRepository.statisticalQuery(request);
                break;
            case COMPANY_CATEGORY:
                response = monthSalesCategoryReportQueryRepository.statisticalQuery(request);
                break;
            default:
                response = monthSalesBasicReportQueryRepository.statisticalQuery(request);
        }

        MonthSalesBasicReportSDO sdo = new MonthSalesBasicReportSDO();
        if(CollectionUtils.isEmpty(response)){
            sdo.setTaskCount(0L);
            sdo.setBeforeMonthMoney(new BigDecimal(0));
            sdo.setMonthMoney(new BigDecimal(0));
            sdo.setTaskCountComplete(0L);
            sdo.setBeforeMonthMoneyComplete(new BigDecimal(0));
            sdo.setMonthMoneyComplete(new BigDecimal(0));
            sdo.setTaskCountRemain(0L);
            sdo.setMonthMoneyRemain(new BigDecimal(0));
            sdo.setBeforeMonthMoneyRemain(new BigDecimal(0));
        }else{
            sdo = response.get(0);
        }
        //任务量
        BigDecimal taskCount = new BigDecimal(sdo.getTaskCount());
        //折前任务金额
        BigDecimal beforeMonthMoney = sdo.getBeforeMonthMoney();
        //折后任务金额
        BigDecimal monthMoney = sdo.getMonthMoney();
        //折后合同金额
        BigDecimal contractMoney = sdo.getContractMoney();
        //任务达成量
        BigDecimal taskCountComplete  = new BigDecimal(sdo.getTaskCountComplete());
        //折前任务金额达成量
        BigDecimal beforeMonthMoneyComplete = sdo.getBeforeMonthMoneyComplete();
        //折后任务金额达成量
        BigDecimal monthMoneyComplete = sdo.getMonthMoneyComplete();
        //任务差量
        //BigDecimal taskCountRemain = taskCountComplete.subtract(taskCount);
        SubtotalViewVO column1 = SubtotalViewVOUtil.getSubtotalVODeltaNoFormat("当月任务差量",SubtotalViewVOUtil.JIAN,new BigDecimal(sdo.getTaskCountRemain()));
        //折前任务差额
        //BigDecimal beforeMonthMoneyRemain = beforeMonthMoneyComplete.subtract(beforeMonthMoney);
        SubtotalViewVO column2 = SubtotalViewVOUtil.getSubtotalVODeltaNoFormat("当月任务差额(折前)",SubtotalViewVOUtil.YUAN,sdo.getBeforeMonthMoneyRemain());
        //折后任务差额
        //BigDecimal monthMoneyRemain = monthMoneyComplete.subtract(monthMoney);
        SubtotalViewVO column3 = SubtotalViewVOUtil.getSubtotalVODeltaNoFormat("当月任务差额(折后)",SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyRemain());
        //折后合同差额
        SubtotalViewVO column4 = SubtotalViewVOUtil.getSubtotalVODeltaNoFormat("当月合同差额(折后)",SubtotalViewVOUtil.YUAN,sdo.getContractMoneyRemain());

        BigDecimal taskCountCompletePercentage = taskCount.compareTo(BigDecimal.ZERO)!=0?taskCountComplete.divide(taskCount,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2):new BigDecimal(0);
        BigDecimal beforeMonthMoneyCompletePercentage = beforeMonthMoney.compareTo(BigDecimal.ZERO)!=0?beforeMonthMoneyComplete.divide(beforeMonthMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2):new BigDecimal(0);
        BigDecimal monthMoneyCompletePercentage = monthMoney.compareTo(BigDecimal.ZERO)!=0?monthMoneyComplete.divide(monthMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2):new BigDecimal(0);
        BigDecimal contractMonthMoneyCompletePercentage = contractMoney.compareTo(BigDecimal.ZERO)!=0?monthMoneyComplete.divide(contractMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2):new BigDecimal(0);
        SubtotalViewVO column5 = SubtotalViewVOUtil.getSubtotalVOFormat("数量已达成百分比",SubtotalViewVOUtil.PERCENT,taskCountCompletePercentage);
        SubtotalViewVO column6 = SubtotalViewVOUtil.getSubtotalVOFormat("金额已达成百分比(折前)",SubtotalViewVOUtil.PERCENT,beforeMonthMoneyCompletePercentage);
        SubtotalViewVO column7 = SubtotalViewVOUtil.getSubtotalVOFormat("金额已达成百分比(折后)",SubtotalViewVOUtil.PERCENT,monthMoneyCompletePercentage);
        SubtotalViewVO column8 = SubtotalViewVOUtil.getSubtotalVOFormat("合同金额已达成百分比(折后)",SubtotalViewVOUtil.PERCENT,contractMonthMoneyCompletePercentage);

        List<SubtotalViewVO> subtotalViewVOList = Lists.newArrayList(column1,column5,column2,column6,column3,column7,column4,column8);
        Result result = Result.listSuccess(subtotalViewVOList,subtotalViewVOList.size());
        return result;
    }

    private void insertTotalRow(List<MonthSalesBasicReportSDO> listResult,QueryMonthSalesReportRequest queryRequest){
        List<MonthSalesBasicReportSDO> newListResult = Lists.newArrayList(listResult);
        //id , type, index
        Map<String,List<Object>> ids = new LinkedHashMap<>();
        int insertTimes = 0;
        String lastDeportmentId = listResult.get(0).getOrgSalesDepartmentId();
        String lastChannelId = listResult.get(0).getOrgSalesChannelId();
        String lastBusinessUnitId = listResult.get(0).getOrgBusinessUnitId();

        //查询上一页的List最后一个
//        if(queryRequest.getStart() != 0){
//            QueryMonthSalesReportRequest prePageRequest = new QueryMonthSalesReportRequest();
//            BeanUtils.copyProperties(queryRequest,prePageRequest);
//            prePageRequest.setStart(queryRequest.getStart()-queryRequest.getLimit());
//            PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesBasicReportQueryRepository.pageQueryMonthSalesBasicReportList(prePageRequest);
//            MonthSalesBasicReportSDO last = pageResult.getContent().get(pageResult.getContent().size()-1);
//            lastDeportmentId = last.getOrgSalesDepartmentId();
//            lastChannelId = last.getOrgSalesChannelId();
//            lastBusinessUnitId = last.getOrgBusinessUnitId();
//        }else{
//            lastDeportmentId = listResult.get(0).getOrgSalesDepartmentId();
//            lastChannelId = listResult.get(0).getOrgSalesChannelId();
//            lastBusinessUnitId = listResult.get(0).getOrgBusinessUnitId();
//        }

        //查询下一页的List第一个
        QueryMonthSalesReportRequest nextPageRequest = new QueryMonthSalesReportRequest();
        BeanUtils.copyProperties(queryRequest,nextPageRequest);
        nextPageRequest.setStart(queryRequest.getStart()+queryRequest.getLimit());
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesBasicReportQueryRepository.pageQueryMonthSalesBasicReportList(nextPageRequest);
        if(CollectionUtils.isNotEmpty(pageResult.getContent())){
            newListResult.add(pageResult.getContent().get(0));
        }else{
            MonthSalesBasicReportSDO bean = new MonthSalesBasicReportSDO();
            bean.setOrgSalesDepartmentId("-1");
            bean.setOrgSalesChannelId("-1");
            bean.setOrgBusinessUnitId("-1");
            newListResult.add(bean);
        }

        Boolean needDepartmentTotal = false;
        Boolean needChannelTotal = false;
        Boolean needBusinessUnitTotal = false;
        //计算出本次查询List，小计插入的位置
        for(int i = 0; i < newListResult.size(); i++){
            MonthSalesBasicReportSDO temp = newListResult.get(i);
            if(!lastDeportmentId.equals(temp.getOrgSalesDepartmentId())){
                ids.put(lastDeportmentId,Lists.newArrayList(GROUPBY_DEPARTMENT,i+insertTimes));
                lastDeportmentId = temp.getOrgSalesDepartmentId();
                insertTimes++;
                needDepartmentTotal = true;
            }
            if(!lastChannelId.equals(temp.getOrgSalesChannelId())){
                ids.put(lastChannelId,Lists.newArrayList(GROUPBY_CHANNEL,i+insertTimes));
                lastChannelId = temp.getOrgSalesChannelId();
                insertTimes++;
                needChannelTotal = true;
            }
            if(!lastBusinessUnitId.equals(temp.getOrgBusinessUnitId())){
                ids.put(lastBusinessUnitId,Lists.newArrayList(GROUPBY_BUSINESSUNIT,i+insertTimes));
                lastBusinessUnitId = temp.getOrgBusinessUnitId();
                insertTimes++;
                needBusinessUnitTotal = true;
            }
        };

        Map<String,MonthSalesBasicReportSDO> departmentMap = null;
        Map<String,MonthSalesBasicReportSDO> channelMap = null;
        Map<String,MonthSalesBasicReportSDO> businessUnitMap = null;
        //所有部门小计
        if(needDepartmentTotal){
            queryRequest.setGroupBy(GROUPBY_DEPARTMENT);
            List<MonthSalesBasicReportSDO> departmentList = monthSalesBasicReportQueryRepository.statisticalQuery(queryRequest);
            departmentMap = departmentList.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgSalesDepartmentId, Function.identity(),(v1,v2)->v1));
        }
        //所有渠道合计
        if(needChannelTotal){
            queryRequest.setGroupBy(GROUPBY_CHANNEL);
            List<MonthSalesBasicReportSDO> channelList = monthSalesBasicReportQueryRepository.statisticalQuery(queryRequest);
            channelMap = channelList.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgSalesChannelId, Function.identity(),(v1, v2)->v1));
        }
        //所有公司总计
        if(needBusinessUnitTotal){
            queryRequest.setGroupBy(GROUPBY_BUSINESSUNIT);
            List<MonthSalesBasicReportSDO> businessUnitList = monthSalesBasicReportQueryRepository.statisticalQuery(queryRequest);
            businessUnitMap = businessUnitList.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgBusinessUnitId, Function.identity(),(v1,v2)->v1));
        }

        //listResult插入小计合计总计行
        for (Map.Entry<String, List<Object>> m : ids.entrySet()) {
            List<Object> tmp = m.getValue();
            if(needDepartmentTotal && tmp.get(0).equals(GROUPBY_DEPARTMENT)){
                MonthSalesBasicReportSDO row = departmentMap.get(m.getKey());
                row.setOrgSalesDepartmentName("部门小计");
                countSalesOrderComplete(row);
                listResult.add((int)tmp.get(1),row);
            }else if(needChannelTotal && tmp.get(0).equals(GROUPBY_CHANNEL)){
                MonthSalesBasicReportSDO row = channelMap.get(m.getKey());
                row.setOrgSalesChannelName("渠道合计");
                countSalesOrderComplete(row);
                listResult.add((int)tmp.get(1),row);
            }else if(needBusinessUnitTotal && tmp.get(0).equals(GROUPBY_BUSINESSUNIT)){
                MonthSalesBasicReportSDO row = businessUnitMap.get(m.getKey());
                row.setOrgBusinessUnitName("分子公司总计");
                countSalesOrderComplete(row);
                listResult.add((int)tmp.get(1),row);
            }
        };
    }

    private void insertTotalRow2(List<MonthSalesBasicReportSDO> listResult,QueryMonthSalesReportRequest queryRequest){
        List<MonthSalesBasicReportSDO> newListResult = Lists.newArrayList(listResult);
        //id , type, index
        Map<String,List<Object>> ids = new LinkedHashMap<>();
        int insertTimes = 0;
        String lastDeportmentId = listResult.get(0).getOrgSalesDepartmentId();
        String lastChannelId = listResult.get(0).getOrgSalesChannelId();
        String lastBusinessUnitId = listResult.get(0).getOrgBusinessUnitId();

        //查询下一页的List第一个
        QueryMonthSalesReportRequest nextPageRequest = new QueryMonthSalesReportRequest();
        BeanUtils.copyProperties(queryRequest,nextPageRequest);
        nextPageRequest.setStart(queryRequest.getStart()+queryRequest.getLimit());
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesCategoryReportQueryRepository.pageQueryMonthSalesCategoryReportSortList(nextPageRequest);
        if(CollectionUtils.isNotEmpty(pageResult.getContent())){
            newListResult.add(pageResult.getContent().get(0));
        }else{
            MonthSalesBasicReportSDO bean = new MonthSalesBasicReportSDO();
            bean.setOrgSalesDepartmentId("-1");
            bean.setOrgSalesChannelId("-1");
            bean.setOrgBusinessUnitId("-1");
            newListResult.add(bean);
        }

        Boolean needDepartmentTotal = false;
        Boolean needChannelTotal = false;
        Boolean needBusinessUnitTotal = false;
        //计算出本次查询List，小计插入的位置
        for(int i = 0; i < newListResult.size(); i++){
            MonthSalesBasicReportSDO temp = newListResult.get(i);
            if(!lastDeportmentId.equals(temp.getOrgSalesDepartmentId())){
                ids.put(lastDeportmentId,Lists.newArrayList(GROUPBY_DEPARTMENT,i+insertTimes));
                lastDeportmentId = temp.getOrgSalesDepartmentId();
                insertTimes++;
                needDepartmentTotal = true;
            }
            if(!lastChannelId.equals(temp.getOrgSalesChannelId())){
                ids.put(lastChannelId,Lists.newArrayList(GROUPBY_CHANNEL,i+insertTimes));
                lastChannelId = temp.getOrgSalesChannelId();
                insertTimes++;
                needChannelTotal = true;
            }
            if(!lastBusinessUnitId.equals(temp.getOrgBusinessUnitId())){
                ids.put(lastBusinessUnitId,Lists.newArrayList(GROUPBY_BUSINESSUNIT,i+insertTimes));
                lastBusinessUnitId = temp.getOrgBusinessUnitId();
                insertTimes++;
                needBusinessUnitTotal = true;
            }
        };

        Map<String,MonthSalesBasicReportSDO> departmentMap = null;
        Map<String,MonthSalesBasicReportSDO> channelMap = null;
        Map<String,MonthSalesBasicReportSDO> businessUnitMap = null;
        //所有部门小计
        if(needDepartmentTotal){
            queryRequest.setGroupBy(GROUPBY_DEPARTMENT);
            List<MonthSalesBasicReportSDO> departmentList = monthSalesCategoryReportQueryRepository.statisticalQuery(queryRequest);
            departmentMap = departmentList.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgSalesDepartmentId, Function.identity(),(v1,v2)->v1));
        }
        //所有渠道合计
        if(needChannelTotal){
            queryRequest.setGroupBy(GROUPBY_CHANNEL);
            List<MonthSalesBasicReportSDO> channelList = monthSalesCategoryReportQueryRepository.statisticalQuery(queryRequest);
            channelMap = channelList.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgSalesChannelId, Function.identity(),(v1,v2)->v1));
        }
        //所有公司总计
        if(needBusinessUnitTotal){
            queryRequest.setGroupBy(GROUPBY_BUSINESSUNIT);
            List<MonthSalesBasicReportSDO> businessUnitList = monthSalesCategoryReportQueryRepository.statisticalQuery(queryRequest);
            businessUnitMap = businessUnitList.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgBusinessUnitId, Function.identity(),(v1,v2)->v1));
        }

        //listResult插入小计合计总计行
        for (Map.Entry<String, List<Object>> m : ids.entrySet()) {
            List<Object> tmp = m.getValue();
            if(needDepartmentTotal && tmp.get(0).equals(GROUPBY_DEPARTMENT)){
                MonthSalesBasicReportSDO row = departmentMap.get(m.getKey());
                row.setOrgSalesDepartmentName("部门小计");
                countSalesOrderComplete(row);
                listResult.add((int)tmp.get(1),row);
            }else if(needChannelTotal && tmp.get(0).equals(GROUPBY_CHANNEL)){
                MonthSalesBasicReportSDO row = channelMap.get(m.getKey());
                row.setOrgSalesChannelName("渠道合计");
                countSalesOrderComplete(row);
                listResult.add((int)tmp.get(1),row);
            }else if(needBusinessUnitTotal && tmp.get(0).equals(GROUPBY_BUSINESSUNIT)){
                MonthSalesBasicReportSDO row = businessUnitMap.get(m.getKey());
                row.setOrgBusinessUnitName("分子公司总计");
                countSalesOrderComplete(row);
                listResult.add((int)tmp.get(1),row);
            }
        };
    }

    private void insertTotalRow3(List<MonthSalesBasicReportSDO> listResult,QueryMonthSalesReportRequest queryRequest){
        List<MonthSalesBasicReportSDO> newListResult = Lists.newArrayList(listResult);
        //id , type, index
        Map<String,List<Object>> ids = new LinkedHashMap<>();
        int insertTimes = 0;
        String lastBusinessUnitId = listResult.get(0).getOrgBusinessUnitId();

        //查询下一页的List第一个
        QueryMonthSalesReportRequest nextPageRequest = new QueryMonthSalesReportRequest();
        BeanUtils.copyProperties(queryRequest,nextPageRequest);
        nextPageRequest.setStart(queryRequest.getStart()+queryRequest.getLimit());
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesCategoryReportQueryRepository.pageQueryMonthSalesCompanyCategoryReportSortList(nextPageRequest);
        if(CollectionUtils.isNotEmpty(pageResult.getContent())){
            newListResult.add(pageResult.getContent().get(0));
        }else{
            MonthSalesBasicReportSDO bean = new MonthSalesBasicReportSDO();
            bean.setOrgBusinessUnitId("-1");
            newListResult.add(bean);
        }

        Boolean needBusinessUnitTotal = false;
        //计算出本次查询List，小计插入的位置
        for(int i = 0; i < newListResult.size(); i++){
            MonthSalesBasicReportSDO temp = newListResult.get(i);
            if(!lastBusinessUnitId.equals(temp.getOrgBusinessUnitId())){
                ids.put(lastBusinessUnitId,Lists.newArrayList(GROUPBY_BUSINESSUNIT,i+insertTimes));
                lastBusinessUnitId = temp.getOrgBusinessUnitId();
                insertTimes++;
                needBusinessUnitTotal = true;
            }
        };

        Map<String,MonthSalesBasicReportSDO> businessUnitMap = null;
        //所有公司总计
        if(needBusinessUnitTotal){
            queryRequest.setGroupBy(GROUPBY_BUSINESSUNIT);
            List<MonthSalesBasicReportSDO> businessUnitList = monthSalesCategoryReportQueryRepository.statisticalQuery(queryRequest);
            businessUnitMap = businessUnitList.stream().collect(Collectors.toMap(MonthSalesBasicReportSDO::getOrgBusinessUnitId, Function.identity(),(v1,v2)->v1));
        }

        //listResult插入小计合计总计行
        for (Map.Entry<String, List<Object>> m : ids.entrySet()) {
            List<Object> tmp = m.getValue();
            if(needBusinessUnitTotal && tmp.get(0).equals(GROUPBY_BUSINESSUNIT)){
                MonthSalesBasicReportSDO row = businessUnitMap.get(m.getKey());
                row.setOrgBusinessUnitName("分子公司总计");
                countSalesOrderComplete(row);
                listResult.add((int)tmp.get(1),row);
            }
        };
    }


    private void countSalesOrderComplete(MonthSalesBasicReportSDO sdo){
        //任务量
        BigDecimal taskCount = new BigDecimal(sdo.getTaskCount());
        //折前任务金额
        BigDecimal beforeMonthMoney = sdo.getBeforeMonthMoney();
        //折后任务金额
        BigDecimal monthMoney = sdo.getMonthMoney();
        //折后合同金额
        BigDecimal contractMoney = sdo.getContractMoney();
        //任务达成量
        BigDecimal taskCountComplete  = new BigDecimal(sdo.getTaskCountComplete());
        //折前任务金额达成量
        BigDecimal beforeMonthMoneyComplete = sdo.getBeforeMonthMoneyComplete();
        //折后任务金额达成量
        BigDecimal monthMoneyComplete = sdo.getMonthMoneyComplete();

        //任务达成量百分比
        BigDecimal taskCountCompletePercentage = taskCount.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):taskCountComplete.divide(taskCount,4,BigDecimal.ROUND_HALF_UP);
        sdo.setTaskCountCompletePercentage(taskCountCompletePercentage);
        //折前任务金额达成百分比
        BigDecimal beforeMonthMoneyCompletePercentage = beforeMonthMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):beforeMonthMoneyComplete.divide(beforeMonthMoney,4,BigDecimal.ROUND_HALF_UP);
        sdo.setBeforeMonthMoneyCompletePercentage(beforeMonthMoneyCompletePercentage);
        //折后任务金额达成百分比
        BigDecimal monthMoneyCompletePercentage = monthMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):monthMoneyComplete.divide(monthMoney,4,BigDecimal.ROUND_HALF_UP);
        sdo.setMonthMoneyCompletePercentage(monthMoneyCompletePercentage);
        //折后合同金额达成百分比
        BigDecimal contractMoneyCompletePercentage = contractMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):monthMoneyComplete.divide(contractMoney,4,BigDecimal.ROUND_HALF_UP);
        sdo.setContractMoneyCompletePercentage(contractMoneyCompletePercentage);
    }

    private Result<List<SubtotalViewVO>> initSubtotalViewVO(){
        SubtotalViewVO column1 = new SubtotalViewVO();
        column1.setLabel("当月任务差量");
        column1.setValue("0");
        column1.setUnit("件");
        SubtotalViewVO column5 = new SubtotalViewVO();
        column5.setLabel("数量已达成百分比");
        column5.setValue("0");
        column5.setDecimal(".00");
        column5.setUnit("%");
        SubtotalViewVO column2 = new SubtotalViewVO();
        column2.setLabel("当月任务差额(折前)");
        column2.setValue("0");
        column2.setDecimal(".00");
        column2.setUnit("元");
        SubtotalViewVO column6 = new SubtotalViewVO();
        column6.setLabel("金额已达成百分比(折前)");
        column6.setValue("0");
        column6.setDecimal(".00");
        column6.setUnit("%");
        SubtotalViewVO column3 = new SubtotalViewVO();
        column3.setLabel("当月任务差额(折后)");
        column3.setValue("0");
        column3.setDecimal(".00");
        column3.setUnit("元");
        SubtotalViewVO column7 = new SubtotalViewVO();
        column7.setLabel("金额已达成百分比(折后)");
        column7.setValue("0");
        column7.setDecimal(".00");
        column7.setUnit("%");
        SubtotalViewVO column4 = new SubtotalViewVO();
        column4.setLabel("当月合同差额(折后)");
        column4.setValue("0");
        column4.setDecimal(".00");
        column4.setUnit("元");
        SubtotalViewVO column8 = new SubtotalViewVO();
        column8.setLabel("合同金额已达成百分比(折后)");
        column8.setValue("0");
        column8.setDecimal(".00");
        column8.setUnit("%");
        Result result = Result.listSuccess(Lists.newArrayList(column1,column5,column2,column6,column3,column7,column4,column8),8);
        return result;
    }

    public void assembleQueryOrganization(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        //组装查询组织
        if(CollectionUtils.isNotEmpty(queryMonthSalesReportRequest.getOrganizationIds())){
            List<OrganizationSDO> orgList = baseDataQueryRepository.batchQueryOrganizationGetList(queryMonthSalesReportRequest.getOrganizationIds());
            List<String> orgBusinessUnitIds = new ArrayList();
            List<String> orgSalesOrganizationIds = new ArrayList();
            List<String> orgSalesChannelIds = new ArrayList();
            List<String> orgSalesDepartmentIds = new ArrayList();
            orgList.forEach(x ->{
                if(Objects.equals(x.getType(), OrganizationTypeEnum.COMPANY.getCode())){
                    orgBusinessUnitIds.add(x.getId());
                }else if(Objects.equals(x.getType(), OrganizationTypeEnum.SALES_ORGANIZATION.getCode())){
                    orgSalesOrganizationIds.add(x.getId());
                }else if(Objects.equals(x.getType(), OrganizationTypeEnum.SALES_CHANNEL.getCode())){
                    orgSalesChannelIds.add(x.getId());
                }else if(Objects.equals(x.getType(), OrganizationTypeEnum.SALES_DEPARTMENT.getCode())){
                    orgSalesDepartmentIds.add(x.getId());
                }
            });
            queryMonthSalesReportRequest.setOrgBusinessUnitIds(orgBusinessUnitIds);
            queryMonthSalesReportRequest.setOrgSalesOrganizationIds(orgSalesOrganizationIds);
            queryMonthSalesReportRequest.setOrgSalesChannelIds(orgSalesChannelIds);
            queryMonthSalesReportRequest.setOrgSalesDepartmentIds(orgSalesDepartmentIds);
        }
    }

    private List<MonthSalesProgressReportVO> converterVO(List<MonthSalesBasicReportSDO> list){
        List<MonthSalesProgressReportVO> result =  list.stream().map( x -> {
            MonthSalesProgressReportVO vo = new MonthSalesProgressReportVO();
            BeanUtils.copyProperties(x,vo);
            vo.setTaskCount(DomUtil.numFormat(x.getTaskCount()));
            vo.setTaskCountComplete(DomUtil.numFormat(x.getTaskCountComplete()));
            vo.setTaskCountRemain(DomUtil.deltaFormat(x.getTaskCountRemain()));
            vo.setTaskCountCompletePercentage(DomUtil.percentFormat(x.getTaskCountCompletePercentage()));
            vo.setBeforeMonthMoney(DomUtil.amountFormat(x.getBeforeMonthMoney()));
            vo.setMonthMoney(DomUtil.amountFormat(x.getMonthMoney()));
            vo.setBeforeMonthMoneyComplete(DomUtil.amountFormat(x.getBeforeMonthMoneyComplete()));
            vo.setMonthMoneyComplete(DomUtil.amountFormat(x.getMonthMoneyComplete()));
            vo.setBeforeMonthMoneyCompletePercentage(DomUtil.percentFormat(x.getBeforeMonthMoneyCompletePercentage()));
            vo.setMonthMoneyCompletePercentage(DomUtil.percentFormat(x.getMonthMoneyCompletePercentage()));
            vo.setBeforeMonthMoneyRemain(DomUtil.differenceFormat(x.getBeforeMonthMoneyRemain()));
            vo.setMonthMoneyRemain(DomUtil.differenceFormat(x.getMonthMoneyRemain()));
            vo.setContractMoney(DomUtil.amountFormat(x.getContractMoney()));
            vo.setContractMoneyComplete(DomUtil.amountFormat(x.getContractMoneyComplete()));
            vo.setContractMoneyCompletePercentage(DomUtil.percentFormat(x.getContractMoneyCompletePercentage()));
            vo.setContractMoneyRemain(DomUtil.differenceFormat(x.getContractMoneyRemain()));
            return vo;
        }).collect(Collectors.toList());
        return result;
    }

    private List<MonthSalesProgressReportExcelVO> converterExcelVO(List<MonthSalesBasicReportSDO> list){
        List<MonthSalesProgressReportExcelVO> result =  list.stream().map( x -> {
            MonthSalesProgressReportExcelVO vo = new MonthSalesProgressReportExcelVO();
            BeanUtils.copyProperties(x,vo);
            vo.setTaskCountCompletePercentage(DomUtil.percentFormat(x.getTaskCountCompletePercentage()));
            vo.setBeforeMonthMoneyCompletePercentage(DomUtil.percentFormat(x.getBeforeMonthMoneyCompletePercentage()));
            vo.setMonthMoneyCompletePercentage(DomUtil.percentFormat(x.getMonthMoneyCompletePercentage()));
            vo.setContractMoneyCompletePercentage(DomUtil.percentFormat(x.getContractMoneyCompletePercentage()));
            return vo;
        }).collect(Collectors.toList());
        return result;
    }

    private List<MonthSalesProgressReportVO> converterComputeVOList(List<MonthSalesBasicReportSDO> list){
        List<MonthSalesProgressReportVO> result =  list.stream().map( x -> {
            MonthSalesProgressReportVO vo = new MonthSalesProgressReportVO();
            BeanUtils.copyProperties(x,vo);
            vo.setTaskCount(DomUtil.numFormat(x.getTaskCount()));
            vo.setTaskCountComplete(DomUtil.numFormat(x.getTaskCountComplete()));
            vo.setTaskCountRemain(DomUtil.deltaFormat(x.getTaskCountRemain()));
            //vo.setTaskCountCompletePercentage(DomUtil.percentFormat(x.getTaskCountCompletePercentage()));
            vo.setBeforeMonthMoney(DomUtil.amountFormat(x.getBeforeMonthMoney()));
            vo.setMonthMoney(DomUtil.amountFormat(x.getMonthMoney()));
            vo.setBeforeMonthMoneyComplete(DomUtil.amountFormat(x.getBeforeMonthMoneyComplete()));
            vo.setMonthMoneyComplete(DomUtil.amountFormat(x.getMonthMoneyComplete()));
            //vo.setBeforeMonthMoneyCompletePercentage(DomUtil.percentFormat(x.getBeforeMonthMoneyCompletePercentage()));
            //vo.setMonthMoneyCompletePercentage(DomUtil.percentFormat(x.getMonthMoneyCompletePercentage()));
            vo.setBeforeMonthMoneyRemain(DomUtil.differenceFormat(x.getBeforeMonthMoneyRemain()));
            vo.setMonthMoneyRemain(DomUtil.differenceFormat(x.getMonthMoneyRemain()));
            vo.setContractMoney(DomUtil.amountFormat(x.getContractMoney()));
            vo.setContractMoneyComplete(DomUtil.amountFormat(x.getContractMoneyComplete()));
            //vo.setContractMoneyCompletePercentage(DomUtil.percentFormat(x.getContractMoneyCompletePercentage()));
            vo.setContractMoneyRemain(DomUtil.differenceFormat(x.getContractMoneyRemain()));

            converterComputeVO(x,vo);
            return vo;
        }).collect(Collectors.toList());
        return result;
    }

    private List<MonthSalesProgressReportExcelVO> converterComputeExcelVOList(List<MonthSalesBasicReportSDO> list){
        List<MonthSalesProgressReportExcelVO> result =  list.stream().map( x -> {
            MonthSalesProgressReportExcelVO vo = new MonthSalesProgressReportExcelVO();
            BeanUtils.copyProperties(x,vo);

            MonthSalesProgressReportVO vo2 = new MonthSalesProgressReportVO();
            converterComputeVO(x,vo2);
            //任务达成量百分比
            vo.setTaskCountCompletePercentage(vo2.getTaskCountCompletePercentage());
            //折前任务金额达成百分比
            vo.setBeforeMonthMoneyCompletePercentage(vo2.getBeforeMonthMoneyCompletePercentage());
            //折后任务金额达成百分比
            vo.setMonthMoneyCompletePercentage(vo2.getMonthMoneyCompletePercentage());
            //折后合同金额达成百分比
            vo.setContractMoneyCompletePercentage(vo2.getContractMoneyCompletePercentage());
            return vo;
        }).collect(Collectors.toList());
        return result;
    }

    private MonthSalesProgressReportVO converterComputeVO(MonthSalesBasicReportSDO sdo,MonthSalesProgressReportVO vo){
        //任务量
        BigDecimal taskCount = new BigDecimal(sdo.getTaskCount());
        //折前任务金额
        BigDecimal beforeMonthMoney = sdo.getBeforeMonthMoney().setScale(2, BigDecimal.ROUND_HALF_UP);
        //折后任务金额
        BigDecimal monthMoney = sdo.getMonthMoney().setScale(2, BigDecimal.ROUND_HALF_UP);
        //折后合同金额
        BigDecimal contractMoney = sdo.getContractMoney().setScale(2, BigDecimal.ROUND_HALF_UP);
        //任务量完成
        BigDecimal taskCountComplete = new BigDecimal(sdo.getTaskCountComplete());
        //折前任务金额完成
        BigDecimal beforeMonthMoneyComplete = sdo.getBeforeMonthMoneyComplete().setScale(2, BigDecimal.ROUND_HALF_UP);
        //折后任务金额完成
        BigDecimal monthMoneyComplete = sdo.getMonthMoneyComplete().setScale(2, BigDecimal.ROUND_HALF_UP);
        //折后合同金额完成
        //BigDecimal contractMoneyComplete = sdo.getContractMoneyComplete().setScale(2, BigDecimal.ROUND_HALF_UP);

        //任务达成量百分比
        BigDecimal taskCountCompletePercentage = taskCount.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0.00):taskCountComplete.divide(taskCount,4,BigDecimal.ROUND_HALF_UP);
        vo.setTaskCountCompletePercentage(DomUtil.percentFormat(taskCountCompletePercentage));
        //折前任务金额达成百分比
        BigDecimal beforeMonthMoneyCompletePercentage = beforeMonthMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0.00):beforeMonthMoneyComplete.divide(beforeMonthMoney,4,BigDecimal.ROUND_HALF_UP);
        vo.setBeforeMonthMoneyCompletePercentage(DomUtil.percentFormat(beforeMonthMoneyCompletePercentage));
        //折后任务金额达成百分比
        BigDecimal monthMoneyCompletePercentage = monthMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0.00):monthMoneyComplete.divide(monthMoney,4,BigDecimal.ROUND_HALF_UP);
        vo.setMonthMoneyCompletePercentage(DomUtil.percentFormat(monthMoneyCompletePercentage));
        //折后合同金额达成百分比
        BigDecimal contractMoneyCompletePercentage = contractMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0.00):monthMoneyComplete.divide(contractMoney,4,BigDecimal.ROUND_HALF_UP);
        vo.setContractMoneyCompletePercentage(DomUtil.percentFormat(contractMoneyCompletePercentage));
        return vo;
    }

    private List<MonthSalesProgressReportViewVO> converterViewVOList(List<MonthSalesBasicReportSDO> list){
        List<MonthSalesProgressReportViewVO> converterResult = list.stream().map( x -> {
            return converterViewVO(x);
        }).collect(Collectors.toList());
        return converterResult;
    }

    private List<MonthSalesProgressReportViewVO> converterViewVOListCompany(List<MonthSalesBasicReportSDO> list, Map<String,MonthSalesBasicReportSDO> lastMonthDataMap, Map<String,Contract> companyContractMap, Date statDate){
        List<MonthSalesProgressReportViewVO> converterResult = list.stream().map( x -> {
            MonthSalesProgressReportViewVO vo = converterViewVOWithUnit(x);
            BigDecimal taskCount = new BigDecimal(x.getTaskCount());
            BigDecimal beforeMonthMoney = x.getBeforeMonthMoney();
            BigDecimal monthMoney = x.getMonthMoney();
            //BigDecimal contractMoney = x.getContractMoney();
            BigDecimal contractMoneyComplete = x.getMonthMoneyComplete();
            vo.setContractMoneyComplete(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,contractMoneyComplete));

            //补充 crm公司合同金额与完成额的计算
            Contract contract = companyContractMap.get(x.getOrgBusinessUnitId());
            if(contract == null){
                vo.setContractMoney("0.00");
                vo.setContractMoneyRemain(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,contractMoneyComplete));
                vo.setContractMoneyCompletePercentage("0");
                vo.setContractMoneyIncrease("-");
            }else{
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(statDate);
                int month = calendar.get(Calendar.MONTH) + 1;
                BigDecimal contractMoney = getContractQuantity(contract,String.valueOf(month));
                BigDecimal contractMoneyRemain = contractMoneyComplete.subtract(contractMoney);
                BigDecimal contractMoneyCompletePercentage = contractMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):contractMoneyComplete.divide(contractMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                contractMoneyCompletePercentage = contractMoneyCompletePercentage.setScale(2);
                vo.setContractMoney(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,contractMoney));
                vo.setContractMoneyRemain(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,contractMoneyRemain));
                vo.setContractMoneyCompletePercentage(contractMoneyCompletePercentage.toString());

                BigDecimal lastContractMoney = new BigDecimal(0);
                if(month == 1){
                    //去年CRM公司合同量
                    int year = calendar.get(Calendar.YEAR) - 1;
                    BatchQueryContractQuantityRequest contractQueryRequest = new BatchQueryContractQuantityRequest();
                    contractQueryRequest.setOrganizationIds(Lists.newArrayList(vo.getOrgBusinessUnitId()));
                    contractQueryRequest.setType("103");
                    contractQueryRequest.setContractYear(String.valueOf(year));
                    contractQueryRequest.setDataSource(ContractDataSourceEnum.CRM.getCode());
                    List<Contract> companyContractList = planContractQuantityRepository.batchQueryContractByOrganiztion(contractQueryRequest);
                    Map<String,Contract> lastYearcontractMap = Nullable.stream(companyContractList).collect(Collectors.toMap(Contract::getOrgBusinessUnitCode, Function.identity(),(v1, v2)->v1));
                    Contract tempContract = lastYearcontractMap.get(x.getOrgBusinessUnitId());
                    if(tempContract != null){
                        lastContractMoney = getContractQuantity(tempContract,"12");
                    }
                }else{
                    lastContractMoney = getContractQuantity(contract,String.valueOf(month-1));//上个月crm公司合同金额
                }

                if(lastContractMoney.compareTo(BigDecimal.ZERO) == 0){
                    vo.setContractMoneyIncrease("-");
                }else{
                    BigDecimal contractMoneyIncrease = (contractMoney.subtract(lastContractMoney)).divide(lastContractMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                    contractMoneyIncrease = contractMoneyIncrease.setScale(2);
                    vo.setContractMoneyIncrease(contractMoneyIncrease.toString());
                }
            }

            MonthSalesBasicReportSDO lastMonth = lastMonthDataMap.get(x.getOrgBusinessUnitId());
            if(lastMonth == null || lastMonth.getTaskCount() == 0){
                vo.setTaskCountIncrease("-");
            }else{
                BigDecimal lastTaskCount = new BigDecimal(lastMonth.getTaskCount());
                BigDecimal taskCountIncrease = (taskCount.subtract(lastTaskCount)).divide(lastTaskCount,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                taskCountIncrease = taskCountIncrease.setScale(2);
                vo.setTaskCountIncrease(taskCountIncrease.toString());
            }

            if(lastMonth == null || lastMonth.getBeforeMonthMoney().compareTo(BigDecimal.ZERO) == 0){
                vo.setBeforeMonthMoneyIncrease("-");
            }else{
                BigDecimal lastBeforeMonthMoney = lastMonth.getBeforeMonthMoney();
                BigDecimal beforeMonthMoneyIncrease = (beforeMonthMoney.subtract(lastBeforeMonthMoney)).divide(lastBeforeMonthMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                beforeMonthMoneyIncrease = beforeMonthMoneyIncrease.setScale(2);
                vo.setBeforeMonthMoneyIncrease(beforeMonthMoneyIncrease.toString());
            }

            if(lastMonth == null || lastMonth.getMonthMoney().compareTo(BigDecimal.ZERO) == 0){
                vo.setMonthMoneyIncrease("-");
            }else{
                BigDecimal lastMonthMoney = lastMonth.getMonthMoney();
                BigDecimal monthMoneyIncrease = (monthMoney.subtract(lastMonthMoney)).divide(lastMonthMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                monthMoneyIncrease = monthMoneyIncrease.setScale(2);
                vo.setMonthMoneyIncrease(monthMoneyIncrease.toString());
            }
            return vo;
        }).collect(Collectors.toList());
        return converterResult;
    }

    private MonthSalesProgressReportViewVO converterViewVO(MonthSalesBasicReportSDO sdo){
        MonthSalesProgressReportViewVO vo = new MonthSalesProgressReportViewVO();
        BeanUtils.copyProperties(sdo,vo);
        vo.setTaskCount(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.JIAN,new BigDecimal(sdo.getTaskCount())));
        vo.setTaskCountComplete(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.JIAN,new BigDecimal(sdo.getTaskCountComplete())));
        vo.setTaskCountRemain(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.JIAN,new BigDecimal(sdo.getTaskCountRemain())));
        vo.setBeforeMonthMoney(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getBeforeMonthMoney()));
        vo.setMonthMoney(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getMonthMoney()));
        vo.setBeforeMonthMoneyComplete(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getBeforeMonthMoneyComplete()));
        vo.setMonthMoneyComplete(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyComplete()));
        vo.setBeforeMonthMoneyRemain(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getBeforeMonthMoneyRemain()));
        vo.setMonthMoneyRemain(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyRemain()));
        vo.setContractMoney(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getContractMoney()));
        vo.setContractMoneyComplete(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyComplete()));
        vo.setContractMoneyRemain(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getContractMoneyRemain()));
        countPercentage(sdo,vo);
        return vo;
    }

    private MonthSalesProgressReportViewVO converterViewVOWithUnit(MonthSalesBasicReportSDO sdo){
        MonthSalesProgressReportViewVO vo = new MonthSalesProgressReportViewVO();
        BeanUtils.copyProperties(sdo,vo);
        vo.setTaskCount(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.JIAN,new BigDecimal(sdo.getTaskCount())));
        vo.setTaskCountComplete(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.JIAN,new BigDecimal(sdo.getTaskCountComplete())));
        vo.setTaskCountRemain(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.JIAN,new BigDecimal(sdo.getTaskCountRemain())));
        vo.setBeforeMonthMoney(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.YUAN,sdo.getBeforeMonthMoney()));
        vo.setMonthMoney(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.YUAN,sdo.getMonthMoney()));
        vo.setBeforeMonthMoneyComplete(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.YUAN,sdo.getBeforeMonthMoneyComplete()));
        vo.setMonthMoneyComplete(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyComplete()));
        vo.setBeforeMonthMoneyRemain(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.YUAN,sdo.getBeforeMonthMoneyRemain()));
        vo.setMonthMoneyRemain(SubtotalViewVOUtil.getSimpleFormat2(SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyRemain()));
        vo.setContractMoney(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getContractMoney()));
        vo.setContractMoneyComplete(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getMonthMoneyComplete()));
        vo.setContractMoneyRemain(SubtotalViewVOUtil.getSimpleFormat(SubtotalViewVOUtil.YUAN,sdo.getContractMoneyRemain()));
        countPercentage(sdo,vo);
        return vo;
    }

    private void countPercentage(MonthSalesBasicReportSDO sdo, MonthSalesProgressReportViewVO vo){
        BigDecimal taskCount = new BigDecimal(sdo.getTaskCount());
        BigDecimal taskCountComplete = new BigDecimal(sdo.getTaskCountComplete());
        BigDecimal beforeMonthMoney = sdo.getBeforeMonthMoney();
        BigDecimal beforeMonthMoneyComplete = sdo.getBeforeMonthMoneyComplete();
        BigDecimal monthMoney = sdo.getMonthMoney();
        BigDecimal monthMoneyComplete = sdo.getMonthMoneyComplete();
        BigDecimal contractMoney = sdo.getContractMoney();

        //String percent = "";
        //任务达成百分比
        BigDecimal taskCountCompletePercentage = taskCount.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):taskCountComplete.divide(taskCount,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        taskCountCompletePercentage = taskCountCompletePercentage.setScale(2);
        //percent = DomUtil.percentFormat(taskCountCompletePercentage);
        vo.setTaskCountCompletePercentage(taskCountCompletePercentage.toString());
        //折前金额达成百分比
        BigDecimal beforeMonthMoneyCompletePercentage = beforeMonthMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):beforeMonthMoneyComplete.divide(beforeMonthMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        beforeMonthMoneyCompletePercentage = beforeMonthMoneyCompletePercentage.setScale(2);
        //percent = DomUtil.percentFormat(beforeMonthMoneyCompletePercentage);
        vo.setBeforeMonthMoneyCompletePercentage(beforeMonthMoneyCompletePercentage.toString());
        //折后金额达成百分比
        BigDecimal monthMoneyCompletePercentage = monthMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):monthMoneyComplete.divide(monthMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        monthMoneyCompletePercentage = monthMoneyCompletePercentage.setScale(2);
        //percent = DomUtil.percentFormat(monthMoneyCompletePercentage);
        vo.setMonthMoneyCompletePercentage(monthMoneyCompletePercentage.toString());
        //折后合同金额达成百分比
        BigDecimal contractMoneyCompletePercentage = contractMoney.compareTo(new BigDecimal(0)) == 0?new BigDecimal(0):monthMoneyComplete.divide(contractMoney,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        contractMoneyCompletePercentage = contractMoneyCompletePercentage.setScale(2);
        //percent = DomUtil.percentFormat(contractMoneyCompletePercentage);
        vo.setContractMoneyCompletePercentage(contractMoneyCompletePercentage.toString());
    }

    private void setDir(QueryMonthSalesReportRequest request){
        if("taskCountCompleteRankNo".equals(request.getDir())){
            request.setDir("task_count_complete_rank_no");
        }else if("beforeMonthMoneyCompleteRankNo".equals(request.getDir())){
            request.setDir("before_month_money_complete_rank_no");
        }else if("monthMoneyCompleteRankNo".equals(request.getDir())){
            request.setDir("month_money_complete_rank_no");
        }else if("contractMoneyCompleteRankNo".equals(request.getDir())){
            request.setDir("contract_money_complete_rank_no");
        }else{
            //request.setDir("task_count_complete_rank_no,before_month_money_complete_rank_no,month_money_complete_rank_no");
        }

        if(request.getAsc() == null || request.getAsc()){
            request.setSortType("ASC");
        }else{
            request.setSortType("DESC");
        }
    }

    private String getLastMonthTimestamp(String date){
        DateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date monthBegin = null;
        try {
            monthBegin = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(monthBegin);
        cal.add(Calendar.MONTH, -1);

        Date lastMonth = null;
        try {
            lastMonth = sdf.parse(sdf.format(cal.getTime()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return Optional.ofNullable(lastMonth).map(o -> String.valueOf(o.getTime())).orElse(null);
    }

    private int getDay(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        return day;
    }

    @Override
    public Result<List<MonthSalesProgressReportExcelVO>> pageQueryMonthSalesBasicReportListExcel(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //组装查询货品类目
        List<String> categoryIds = queryMonthSalesReportRequest.getScItemCategoryIds();
        if(CollectionUtils.isNotEmpty(categoryIds)){
            //查询类目可能是蒙牛常温等根类目，要排除这种情况
            categoryIds = categoryIds.stream().filter(x -> !x.startsWith("###")).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(categoryIds)){
                List<String> scItemRootCategoryIds = new ArrayList();
                List<String> scItemLeafCategoryIds = new ArrayList();
                List<CategorySDO> categoryList = baseDataQueryRepository.batchQueryCategoryGetList(categoryIds);
                categoryList.forEach(x -> {
                    if(Objects.equals(x.getRootCategoryId(), x.getParentCategoryId())){
                        scItemRootCategoryIds.add(x.getCategoryId());
                    }else{
                        scItemLeafCategoryIds.add(x.getCategoryId());
                    }
                });
                queryMonthSalesReportRequest.setScItemRootCategoryIds(scItemRootCategoryIds);
                queryMonthSalesReportRequest.setScItemLeafCategoryIds(scItemLeafCategoryIds);
            }
        }

        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesBasicReportQueryRepository.pageQueryMonthSalesBasicReportList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportExcelVO> converterResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
        }else {
            //填充部门小计，渠道合计，公司总计
            insertTotalRow(listResult,queryMonthSalesReportRequest);
            //数据格式转换
            converterResult = converterExcelVO(listResult);
        }
        return Result.listSuccess(converterResult,pageResult.getTotal());
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportExcelVO>> pageQueryMonthSalesEmployeeRankReportListExcel(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //排序
        setDir(queryMonthSalesReportRequest);
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesEmployeeRankReportQueryRepository.pageQueryMonthSalesEmployeeBankReportList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportExcelVO> converterResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
        }else {
            //重新赋值排序号
            resetEmployeeRankSortNo(queryMonthSalesReportRequest,listResult);
            //数据格式转换
            converterResult = converterExcelVO(listResult);
        }
        return Result.listSuccess(converterResult,pageResult.getTotal());
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportExcelVO>> pageQueryMonthSalesDepartmentRankReportListExcel(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //排序
        setDir(queryMonthSalesReportRequest);
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesDepartmentRankReportQueryRepository.pageQueryMonthSalesDepartmentBankReportList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportExcelVO> converterResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
        }else {
            //重新赋值排序号
            resetDepartmentRankSortNo(queryMonthSalesReportRequest,listResult);
            //数据格式转换
            converterResult = converterExcelVO(listResult);
        }
        return Result.listSuccess(converterResult,pageResult.getTotal());
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportExcelVO>> pageQueryMonthSalesChannelRankReportListExcel(QueryMonthSalesReportRequest queryMonthSalesReportRequest){
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        //部门用户查询直接返回空值
        if(CollectionUtils.isNotEmpty(queryMonthSalesReportRequest.getOrgSalesDepartmentIds())){
            Map<String,Object> ext = new HashMap<>();
            ext.put("statistic",initSubtotalViewVO());
            Result result = Result.listSuccess(new ArrayList<MonthSalesProgressReportVO>(),0);
            result.setExt(ext);
            return result;
        }
        //排序
        setDir(queryMonthSalesReportRequest);
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesChannelRankReportQueryRepository.pageQueryMonthSalesChannelBankReportList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportExcelVO> converterResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
        }else {
            //重新赋值排序号
            resetChannelRankSortNo(queryMonthSalesReportRequest,listResult);
            //数据格式转换
            converterResult = converterExcelVO(listResult);
        }
        return Result.listSuccess(converterResult,pageResult.getTotal());
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportExcelVO>> pageQueryMonthSalesCategoryReportListExcel(QueryMonthSalesReportRequest queryMonthSalesReportRequest) {
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesCategoryReportQueryRepository.pageQueryMonthSalesCategoryReportSortList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportExcelVO> converterResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
        }else {
            //填充部门小计，渠道合计，公司总计
            insertTotalRow2(listResult,queryMonthSalesReportRequest);
            //数据格式转换
            converterResult = converterExcelVO(listResult);
        }
        return Result.listSuccess(converterResult,pageResult.getTotal());
    }

    @Override
    @FacadeInvoker
    public Result<List<MonthSalesProgressReportExcelVO>> pageQueryMonthSalesCompanyCategoryReportListExcel(QueryMonthSalesReportRequest queryMonthSalesReportRequest) {
        if(StringUtil.isBlank(queryMonthSalesReportRequest.getStatisticalDate())){
            throw new FacadeException(ErrorMessage.code("OTS-01-010-01-15-001"));
        }
        PageResult<List<MonthSalesBasicReportSDO>> pageResult = monthSalesCategoryReportQueryRepository.pageQueryMonthSalesCompanyCategoryReportSortList(queryMonthSalesReportRequest);
        List<MonthSalesBasicReportSDO> listResult = pageResult.getContent();
        List<MonthSalesProgressReportExcelVO> converterResult = null;
        //查询为空，初始化列表数据
        if(CollectionUtils.isEmpty(listResult)){
            converterResult = new ArrayList<>();
        }else {
            //填充部门小计，渠道合计，公司总计
            insertTotalRow3(listResult,queryMonthSalesReportRequest);
            //数据格式转换
            converterResult = converterComputeExcelVOList(listResult);
        }
        return Result.listSuccess(converterResult,pageResult.getTotal());
    }


    public BigDecimal getContractQuantity(Contract contract, String month){
        BigDecimal amount = new BigDecimal(0);
        switch (month){
            case "1" :
                amount = new BigDecimal(contract.getJanAmount());
                break;
            case "2" :
                amount = new BigDecimal(contract.getFebAmount());
                break;
            case "3" :
                amount = new BigDecimal(contract.getMarAmount());
                break;
            case "4" :
                amount = new BigDecimal(contract.getAprAmount());
                break;
            case "5" :
                amount = new BigDecimal(contract.getMayAmount());
                break;
            case "6" :
                amount = new BigDecimal(contract.getJuneAmount());
                break;
            case "7" :
                amount = new BigDecimal(contract.getJulyAmount());
                break;
            case "8" :
                amount = new BigDecimal(contract.getAugAmount());
                break;
            case "9" :
                amount = new BigDecimal(contract.getSeptAmount());
                break;
            case "10" :
                amount = new BigDecimal(contract.getOctAmount());
                break;
            case "11" :
                amount = new BigDecimal(contract.getNovAmount());
                break;
            case "12" :
                amount = new BigDecimal(contract.getDecAmount());
                break;
        }
        return amount.divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);
    }

}
